День шестьдесят седьмой. #Оффтоп
Нашёл ещё один интересный канал на YouTube про C# и .Net разработку - IAmTimCorey. https://www.youtube.com/user/IAmTimCorey/ Сразу предупреждаю, все видео на английском, поэтому кто ещё не изучил... это ваши проблемы)))
Тим - разработчик софта, тренер и консультант, имеющий награды Microsoft MVP, PMP и MCP, а также Intel Software Innovator. Цель канала - упростить изучение разработки ПО. Видео на канале самые разнообразные: базовые понятия, инструменты и советы по C#, паттерны проектирования, создание приложения на C# с нуля, связанные технологии (ASP.NET MVC, Azure, SQL Data Tools и т.п.).
Видео не из коротких (от 40 до 90 минут), потому что объясняется всё достаточно подробно. Но и нельзя сказать, что сильно затянуто. Я смотрю для повторения темы либо фоном, либо на скорости 1.5x. Кроме того, есть подборка Weekly Challenge. Короткое, на пару минут, видео с заданием по C# на определённую тему. Можно решить самому, а потом посмотреть предложенное решение по ссылке в описании к видео. Самое главное, что канал не заброшен. Последнее Weekly Challenge совсем свежее, выдано 4 апреля.
Кроме того, у Тима есть сайт с текстовыми версиями и решениями Weekly Challenge, а также блогом: https://www.iamtimcorey.com
Нашёл ещё один интересный канал на YouTube про C# и .Net разработку - IAmTimCorey. https://www.youtube.com/user/IAmTimCorey/ Сразу предупреждаю, все видео на английском, поэтому кто ещё не изучил... это ваши проблемы)))
Тим - разработчик софта, тренер и консультант, имеющий награды Microsoft MVP, PMP и MCP, а также Intel Software Innovator. Цель канала - упростить изучение разработки ПО. Видео на канале самые разнообразные: базовые понятия, инструменты и советы по C#, паттерны проектирования, создание приложения на C# с нуля, связанные технологии (ASP.NET MVC, Azure, SQL Data Tools и т.п.).
Видео не из коротких (от 40 до 90 минут), потому что объясняется всё достаточно подробно. Но и нельзя сказать, что сильно затянуто. Я смотрю для повторения темы либо фоном, либо на скорости 1.5x. Кроме того, есть подборка Weekly Challenge. Короткое, на пару минут, видео с заданием по C# на определённую тему. Можно решить самому, а потом посмотреть предложенное решение по ссылке в описании к видео. Самое главное, что канал не заброшен. Последнее Weekly Challenge совсем свежее, выдано 4 апреля.
Кроме того, у Тима есть сайт с текстовыми версиями и решениями Weekly Challenge, а также блогом: https://www.iamtimcorey.com
День шестьдесят восьмой. #Оффтоп
Я уже писал, что не считаю себя труЪ программистом. В моём понимании настоящие программисты работают над созданием сложных систем и эффективных алгоритмов, создают операционные системы и языки программирования, а также программы ИИ, обыгрывающие человека в шахматы или го. А остальные, и я в том числе, разработчики, которые пользуются плодами первых. И 99% нашей работы, давайте по-честноку, сбор целого из готовых кусочков и небольшая доработка напильником, без сильного напряжения мозга. Если что, я не хотел никого обидеть)))
А поэтому мне всегда нравились ролики, в которых описываются либо базовые алгоритмы (о них, может, сделаю отдельную серию постов), либо решения интересных задач из реального мира. Вот, к примеру, наткнулся в рекомендациях ютуба на видео из курса MIT 6.S095 «Programming for the Puzzled». https://www.youtube.com/watch?v=auK3PSZoidc
В часовом видео, оригинально названном «Вы больше никогда не захотите играть в судоку», описан алгоритм нахождения решения судоку. Сначала прямо в лоб, затем применяются некоторые усовершенствования, чтобы оптимизировать его работу. И какой бы трудной задача ни казалась изначально, в реальности всё решение сводится к 40 строчкам кода и не содержит взрывающих мозг сложностей. Кстати, прекрасный пример красивого и эффективного применения рекурсии. Код в видео написан на Python, но, думаю, что даже тем, кто не знаком с синтаксисом этого языка, будет в принципе понятна суть. Да, и, как это всегда бывает с самыми интересными материалами по программированию, видео на английском.
Я уже писал, что не считаю себя труЪ программистом. В моём понимании настоящие программисты работают над созданием сложных систем и эффективных алгоритмов, создают операционные системы и языки программирования, а также программы ИИ, обыгрывающие человека в шахматы или го. А остальные, и я в том числе, разработчики, которые пользуются плодами первых. И 99% нашей работы, давайте по-честноку, сбор целого из готовых кусочков и небольшая доработка напильником, без сильного напряжения мозга. Если что, я не хотел никого обидеть)))
А поэтому мне всегда нравились ролики, в которых описываются либо базовые алгоритмы (о них, может, сделаю отдельную серию постов), либо решения интересных задач из реального мира. Вот, к примеру, наткнулся в рекомендациях ютуба на видео из курса MIT 6.S095 «Programming for the Puzzled». https://www.youtube.com/watch?v=auK3PSZoidc
В часовом видео, оригинально названном «Вы больше никогда не захотите играть в судоку», описан алгоритм нахождения решения судоку. Сначала прямо в лоб, затем применяются некоторые усовершенствования, чтобы оптимизировать его работу. И какой бы трудной задача ни казалась изначально, в реальности всё решение сводится к 40 строчкам кода и не содержит взрывающих мозг сложностей. Кстати, прекрасный пример красивого и эффективного применения рекурсии. Код в видео написан на Python, но, думаю, что даже тем, кто не знаком с синтаксисом этого языка, будет в принципе понятна суть. Да, и, как это всегда бывает с самыми интересными материалами по программированию, видео на английском.
YouTube
Puzzle 8: You Won't Want to Play Sudoku Again
MIT 6.S095 Programming for the Puzzled, IAP 2018
View the complete course: https://ocw.mit.edu/6-S095IAP18
Instructor: Srini Devadas
Are Sudoku puzzles too difficult or tedious for you? Would you rather write a computer program that solves any Sudoku puzzle…
View the complete course: https://ocw.mit.edu/6-S095IAP18
Instructor: Srini Devadas
Are Sudoku puzzles too difficult or tedious for you? Would you rather write a computer program that solves any Sudoku puzzle…
День шестьдесят девятый. #CSharp8
Новые функции в C# 8.
1. Реализация по Умолчанию Интерфейсных Методов
Эта функция помогает вам добавлять функциональность к интерфейсам ваших библиотек, при этом поддерживая обратную совместимость с кодом, написанным для предыдущих версий этих интерфейсов.
Сейчас после того, как вы опубликовали интерфейс, «игра окончена». Вы не можете добавлять члены к интерфейсу без того, чтобы сломать все существующие его реализации.
C# 8.0 позволяет вам предоставить тело члена интерфейса. Поэтому, если кто-то не реализует этот член (возможно, потому что его ещё не существовало на момент написания кода), они просто будут использовать реализацию по умолчанию.
Преимущества
Вы можете добавлять функциональность к интерфейсам, не нарушая совместимость с предыдущими версиями этих интерфейсов.
Недостатки
Это нужно использовать с осторожностью. В противном случае можно легко нарушить принципы единственной ответственности. Подумайте, прежде чем использовать этот инструмент, нет ли другого, более элегантного решения вашей проблемы.
Источник: https://www.c-sharpcorner.com/article/c-sharp-8-features/
Новые функции в C# 8.
1. Реализация по Умолчанию Интерфейсных Методов
Эта функция помогает вам добавлять функциональность к интерфейсам ваших библиотек, при этом поддерживая обратную совместимость с кодом, написанным для предыдущих версий этих интерфейсов.
Сейчас после того, как вы опубликовали интерфейс, «игра окончена». Вы не можете добавлять члены к интерфейсу без того, чтобы сломать все существующие его реализации.
C# 8.0 позволяет вам предоставить тело члена интерфейса. Поэтому, если кто-то не реализует этот член (возможно, потому что его ещё не существовало на момент написания кода), они просто будут использовать реализацию по умолчанию.
interface ILoggerКласс
{
void Log(LogLevel level, string message);
// Новый перегруженный метод
void Log(Exception ex) => Log(LogLevel.Error, ex.ToString());
}
class ConsoleLogger : ILogger
{
public void Log(LogLevel level, string message) { ... }
// Метод Log(Exception) получает реализацию по умолчанию
}
ConsoleLogger
не имеет реализации перегруженного метода Log(Exception)
интерфейса ILogger
, поскольку был объявлен до внесения изменений в интерфейс. Теперь вы можете безопасно добавлять новые члены в существующие публичные интерфейсы, если вы предоставляете реализацию по умолчанию для уже существующих реализаторов.Преимущества
Вы можете добавлять функциональность к интерфейсам, не нарушая совместимость с предыдущими версиями этих интерфейсов.
Недостатки
Это нужно использовать с осторожностью. В противном случае можно легко нарушить принципы единственной ответственности. Подумайте, прежде чем использовать этот инструмент, нет ли другого, более элегантного решения вашей проблемы.
Источник: https://www.c-sharpcorner.com/article/c-sharp-8-features/
👍1
День семидесятый. #ЗаметкиНаПолях
For Или Foreach в C#
Многие программисты до сих пор путаются, когда использовать цикл
Внутри цикла
Дело в том,
Кроме того, в общем случае
Подводя итог, когда вам нужна простота чтения кода, используйте
Источник: https://www.c-sharpcorner.com/article/for-vs-foreach-in-c-sharp/
For Или Foreach в C#
Многие программисты до сих пор путаются, когда использовать цикл
for
, а когда foreach
. Рассмотрим перебор элементов коллекции в обоих циклах.List<Employee> employees = GetEmployeesList();Цикл for для списка будет выглядеть примерно так:
for (int i = 0; i < employees.Count; i++)Заметьте, что вы можете напрямую обращаться к элементам списка по индексу.
{
Console.WriteLine(employees[i].Age);
}
Внутри цикла
foreach
вы можете напрямую обращаться к каждому элементу: foreach(Employee emp in Employees)Заметьте, что цикл
{
Console.WriteLine(emp.Age);
}
foreach
создаёт копию коллекции, по которой вы проходите. Это означает, что, если вы хотите выполнить операцию присваивания на элементе коллекции, вы не сможете этого сделать:int[] numbers = { 1, 2, 3, 4, 5, 6 };Этот код приводит к ошибке
foreach (int item in numbers)
{
item++;
}
CS1656: Cannot assign to 'item' because it is a 'foreach iteration variable' (Невозможно выполнить присваивание переменной item, поскольку это ‘переменная итерации цикла foreach’)
.Дело в том,
item
здесь не ссылается на элемент массива, это просто временная переменная, и вы не можете присваивать ей значения.Кроме того, в общем случае
foreach
требует больше времени и дополнительную память, по сравнению с for
, поскольку использует методы GetEnumarator()
и Next()
интерфейса IEnumarable
.Подводя итог, когда вам нужна простота чтения кода, используйте
foreach
, когда требуется доступ к элементам внутри цикла, а также критична производительность, используйте for
. Источник: https://www.c-sharpcorner.com/article/for-vs-foreach-in-c-sharp/
День семьдесят первый. #CSharp8
Новые функции в C# 8.
2. Обнуляемый Ссылочный Тип
В C#8 можно объявлять обнуляемый контекст с помощью аннотации
Для необнуляемых ссылочных типов компилятор использует анализ потока, чтобы убедиться, что локальные переменные инициализированы не-
Обнуляемые ссылочные типы не проверяются на присваивание
Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
Новые функции в C# 8.
2. Обнуляемый Ссылочный Тип
В C#8 можно объявлять обнуляемый контекст с помощью аннотации
#nullable
. Внутри него любые переменные ссылочного типа считаются необнуляемыми. Если вы хотите присвоить ссылочному типу null
, нужно явно объявить обнуляемый тип переменной с помощью <тип>?
.Для необнуляемых ссылочных типов компилятор использует анализ потока, чтобы убедиться, что локальные переменные инициализированы не-
null
значением. Все поля должны быть инициализированы в конструкторе. Компилятор выдаёт предупреждение, если переменная не объявляется вызовом любого из доступных конструкторов или инициализатором.Обнуляемые ссылочные типы не проверяются на присваивание
null
, однако компилятор использует анализ потока, чтобы убедиться, что переменная обнуляемого типа не содержит null
, прежде чем к ней обращается код или она присваивается переменной необнуляемого типа.Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
День семьдесят второй. #CSharp8
Новые функции в C# 8.
3. Продвинутое Сопоставление с Шаблоном
Сопоставление выражения с шаблоном предоставляет инструменты для сравнения по форме связанных, но разных типов данных. В C# 7.0 был представлен синтаксис шаблонов типа и шаблонов констант, используя выражения
C# 8.0 расширяет эту функциональность, так что вы можете использовать больше шаблонных выражений в разнообразных местах вашего кода. Используйте эти функции, когда ваши данные и функционал разделены, когда ваши алгоритмы не зависят от типа объекта во время выполнения. В дополнение к новым шаблонам в новых местах, в C# 8.0 вводятся рекурсивные шаблоны. Результат любого шаблона выражения – это выражение. Рекурсивный шаблон – это просто шаблон выражения, применённый к результату другого шаблона выражения.
Преимущества
Рекурсивное сопоставление с шаблоном помогает вам разбить структуры данных на компоненты и использовать их в очень удобном и компактном синтаксисе. Несмотря на то, что сопоставление с шаблоном эквивалентно последовательности выражений if-then, оно помогает вам писать код в стиле функционального программирования.
Недостатки
В сложных выражениях синтаксис может быть хитрым и сложным для понимания.
В следующем примере шаблон выражения используется для сопоставления структуры с шаблоном:
Шаблон свойства позволяет вам сопоставить свойства исследуемого объекта. В следующем примере метод рассчитывает налог с продаж в зависимости от штата (свойство
Некоторые типы включают метод
Источники:
- https://www.c-sharpcorner.com/article/c-sharp-8-features/
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
Новые функции в C# 8.
3. Продвинутое Сопоставление с Шаблоном
Сопоставление выражения с шаблоном предоставляет инструменты для сравнения по форме связанных, но разных типов данных. В C# 7.0 был представлен синтаксис шаблонов типа и шаблонов констант, используя выражения
is
и switch
. C# 8.0 расширяет эту функциональность, так что вы можете использовать больше шаблонных выражений в разнообразных местах вашего кода. Используйте эти функции, когда ваши данные и функционал разделены, когда ваши алгоритмы не зависят от типа объекта во время выполнения. В дополнение к новым шаблонам в новых местах, в C# 8.0 вводятся рекурсивные шаблоны. Результат любого шаблона выражения – это выражение. Рекурсивный шаблон – это просто шаблон выражения, применённый к результату другого шаблона выражения.
Преимущества
Рекурсивное сопоставление с шаблоном помогает вам разбить структуры данных на компоненты и использовать их в очень удобном и компактном синтаксисе. Несмотря на то, что сопоставление с шаблоном эквивалентно последовательности выражений if-then, оно помогает вам писать код в стиле функционального программирования.
Недостатки
В сложных выражениях синтаксис может быть хитрым и сложным для понимания.
В следующем примере шаблон выражения используется для сопоставления структуры с шаблоном:
var point = new 3DPoint(1, 2, 3); //x=1, y=2, z=3Шаблоны свойств
if (point is 3DPoint(1, var myY, _))
{
// Этот код будет выполнен, только если point.X == 1
// myY – это новая переменная,
// которая будет доступна только в этом блоке
// Третий член объекта игнорируется спецсимволом _
}
Шаблон свойства позволяет вам сопоставить свойства исследуемого объекта. В следующем примере метод рассчитывает налог с продаж в зависимости от штата (свойство
State
извлекается из передаваемого объекта типа Address
). Расчёт этого налога не является ответственностью класса Address
, поскольку он может изменяться гораздо чаще, чем структура адреса:public static decimal ComputeSalesTax(Address location, decimal salePrice) =>Позиционные шаблоны
location switch
{
{ State: "WA" } => salePrice * 0.06M,
{ State: "MN" } => salePrice * 0.075M,
{ State: "MI" } => salePrice * 0.05M,
// ...
_ => 0M
};
Некоторые типы включают метод
Deconstruct
, который деконструирует свойства в отдельные переменные. Когда доступен метод Deconstruct
, вы можете использовать позиционные шаблоны для сопоставления свойств с шаблоном. Рассмотрим следующий класс точки с координатами X
и Y
:public class PointТакже у нас имеется перечисление, представляющее собой позицию точки в системе координат: неизвестна, в центре, в первом квадратне, во втором квадранте, …, на оси координат:
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) =>
(x, y) = (X, Y);
}
public enum QuadrantСледующий метод использует позиционный шаблон для извлечения значений
{
Unknown,
Origin,
One,
Two,
Three,
Four,
OnBorder
}
x
и y
, а также использует условие when
для определения квадранта:static Quadrant GetQuadrant(Point point) => point switchШаблон пустого кортежа
{
(0, 0) => Quadrant.Origin,
var (x, y) when x > 0 && y > 0 => Quadrant.One,
var (x, y) when x < 0 && y > 0 => Quadrant.Two,
var (x, y) when x < 0 && y < 0 => Quadrant.Three,
var (x, y) when x > 0 && y < 0 => Quadrant.Four,
var (_, _) => Quadrant.OnBorder,
_ => Quadrant.Unknown
};
(_, _)
соответствует случаю, когда либо x
, либо y
равно 0, но не оба. Выражение switch
должно либо возвращать значение, либо выбрасывать исключение. Если ни один из вариантов не находит соответствия, выражение switch
выбрасывает исключение. Компилятор выдаст предупреждение, если вы не укажете все возможные варианты в выражении switch
.Источники:
- https://www.c-sharpcorner.com/article/c-sharp-8-features/
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
День семьдесят третий. #CSharp8
Новые функции в C# 8.
4. Асинхронные потоки
Начиная с C# 8.0 вы можете создавать и потреблять потоки асинхронно. Метод, возвращающий асинхронный поток, имеет три свойства:
1. Объявляется с модификатором
2. Возвращает
3. Содержит выражения
Потребитель асинхронного потока должен добавить ключевое слово
Следующий код генерирует последовательность от 0 до 19 с ожиданием 100ms между генерациями каждого числа. Затем можно перебрать последовательность, используя выражение
Заметьте, что для выполнения этого кода требуется установить SDK .NET Core 3.0 и использовать его в качестве Target framework в свойствах проекта. А чтобы он появился в этом списке, возможно, потребуется отметить флажок “Use previews of the .NET Core SDK” в Tools > Options > Projects and Solutions > .NET Core и перезагрузить Visual Studio.
Преимущества
Асинхронные потоки предоставляют замечательную возможность представить асинхронные источники данных, которые могут контролироваться потребителем. Например, при загрузке данных из сети, мы хотели бы создать асинхронную коллекцию, которая возвращает данные по частям, как только те становятся доступными.
Источники:
- https://www.c-sharpcorner.com/article/c-sharp-8-features/
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
Новые функции в C# 8.
4. Асинхронные потоки
Начиная с C# 8.0 вы можете создавать и потреблять потоки асинхронно. Метод, возвращающий асинхронный поток, имеет три свойства:
1. Объявляется с модификатором
async
.2. Возвращает
IAsyncEnumerable<T>
.3. Содержит выражения
yield return
, чтобы возвращать последующие элементы из асинхронного потока.Потребитель асинхронного потока должен добавить ключевое слово
await
перед ключевым словом foreach
при переборе элементов потока. Добавление ключевого слова await
требует, чтобы метод, который перечисляет элементы асинхронного потока, был объявлен с модификатором async
и возвращал тип, разрешенный для асинхронного метода. Обычно это означает возврат типа Task
или Task<TResult>
, а также может быть ValueTask
или ValueTask<TResult>
. Метод может как потреблять, так и производить асинхронный поток, что значит, что он будет возвращать IAsyncEnumerable<T>
. Следующий код генерирует последовательность от 0 до 19 с ожиданием 100ms между генерациями каждого числа. Затем можно перебрать последовательность, используя выражение
await foreach
:using System;
using System.Threading.Tasks;
using System.Collections.Generic;
static async Task Main(string[] args)
{
await foreach (var number in GenerateSequence())
{
Console.WriteLine(number);
}
}
public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(100);
yield return i;
}
}
Заметьте, что для выполнения этого кода требуется установить SDK .NET Core 3.0 и использовать его в качестве Target framework в свойствах проекта. А чтобы он появился в этом списке, возможно, потребуется отметить флажок “Use previews of the .NET Core SDK” в Tools > Options > Projects and Solutions > .NET Core и перезагрузить Visual Studio.
Преимущества
Асинхронные потоки предоставляют замечательную возможность представить асинхронные источники данных, которые могут контролироваться потребителем. Например, при загрузке данных из сети, мы хотели бы создать асинхронную коллекцию, которая возвращает данные по частям, как только те становятся доступными.
Источники:
- https://www.c-sharpcorner.com/article/c-sharp-8-features/
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
День семьдесят четвёртый. #CSharp8
Новые функции в C# 8.
5. Индексы и диапазоны
Диапазоны и индексы предоставляют краткий синтаксис указания поддиапазонов элементов массива или типов
Вы можете указать индекс с конца, используя оператор
Вы можете указать диапазон с помощью оператора
Рассмотрим следующий массив строк, обозначенный индексами с начала и с конца:
Вы можете получить последнее слово с помощью индекса
Заметьте, что для использования диапазонов требуется установить SDK .NET Core 3.0 и использовать его в качестве Target framework в свойствах проекта. А чтобы он появился в этом списке, возможно, потребуется отметить флажок “Use previews of the .NET Core SDK” в Tools > Options > Projects and Solutions > .NET Core и перезагрузить Visual Studio.
Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
Новые функции в C# 8.
5. Индексы и диапазоны
Диапазоны и индексы предоставляют краткий синтаксис указания поддиапазонов элементов массива или типов
Span<T>
или ReadOnlySpan<T>
.Вы можете указать индекс с конца, используя оператор
^
. Выражение array[2]
означает "2й элемент с начала". Теперь можно использовать array[^2]
, что означает "2й элемент с конца". Индекс ^0 означает "конец", то есть индекс, следующий за последним элементом.Вы можете указать диапазон с помощью оператора
..
. Например, 0..^0
обозначает весь диапазон массива: 0
с начала до, но не включая, 0
с конца. Любой из операндов оператора может быть как индексом "с начала", так и "с конца". Более того, любой из операндов может быть опущен. По умолчанию 0
– начальный индекс, ^0
– конечный индекс.Рассмотрим следующий массив строк, обозначенный индексами с начала и с конца:
var words = new string[]Индекс каждого элемента усиливает концепцию "с начала" и "с конца", а диапазоны исключают конец диапазона. "Старт" массива – это первый элемент, а "конец" массива находится за последним элементом.
{
// с начала с конца
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumped", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
};
Вы можете получить последнее слово с помощью индекса
^1
:Console.WriteLine($"The last word is {words[^1]}");Следующий код создаёт поддиапазон со словами "quick", "brown" и "fox". Он включает элементы с
// выведет "dog"
words[1]
до words[3]
. Элемент words[4]
не входит в диапазон.var quickBrownFox = words[1..4];Следующий код создаёт поддиапазон со словами "lazy" и "dog". Он включает элементы
words[^2]
и words[^1]
. Конечный индекс words[^0]
не включается:var lazyDog = words[^2..^0];Следующие примеры создают диапазоны, открытые с начала, с конца и с обоих концов:
var allWords = words[..]; // содержит все словаВы также можете объявлять диапазоны как переменные, которые потом могут использоваться внутри квадратных скобок:
var firstPhrase = words[..4]; // слова от "The" до "fox"
var lastPhrase = words[6..]; // слова "the", "lazy" и "dog"
Range phrase = 1..4;Заметьте, что, если вы укажете неверный диапазон, где начальное значение больше конечного, то будет выброшено исключение времени выполнения
var text = words[phrase];
System.OverflowException
, например:var invalidRange = words[5..2];При этом компилятор не выдаёт ошибок или предупреждений во время компиляции, даже если вы явно указываете большее начальное значение (по крайней мере в нынешней версии).
var invalidEnd = words[6..^4];
Заметьте, что для использования диапазонов требуется установить SDK .NET Core 3.0 и использовать его в качестве Target framework в свойствах проекта. А чтобы он появился в этом списке, возможно, потребуется отметить флажок “Use previews of the .NET Core SDK” в Tools > Options > Projects and Solutions > .NET Core и перезагрузить Visual Studio.
Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
День семьдесят пятый. #CSharp8
Новые функции в C# 8.
6. Декларации using
Декларация
Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
Новые функции в C# 8.
6. Декларации using
Декларация
using
– это определение переменной, которому предшествует ключевое слово using
. Оно сообщает компилятору, что определяемая переменная должна быть высвобождена в конце текущего блока кода: static void WriteLinesToFile(IEnumerable<string> lines)В предыдущем примере переменная file освобождается перед тем, как в коде встречается закрывающая скобка метода. Это конец блока, в котором она определена. Предыдущий пример аналогичен использованию блока using:
{
using var file = new System.IO.StreamWriter("WriteLines2.txt");
foreach (string line in lines)
{
file.WriteLine(line);
}
// переменная file высвобождается здесь
}
using (var file = new System.IO.StreamWriter("WriteLines2.txt"))В обоих случаях компилятор вызывает метод
{
// …
}
Dispose()
. Компилятор выбросит ошибку, если выражение в операторе using
не является освобождаемым.Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
День семьдесят шестой. #CSharp8
Новые функции в C# 8.
7. Статические локальные функции
Вы теперь можете добавлять модификатор
Рассмотрим следующий код. Локальная функция
Новые функции в C# 8.
7. Статические локальные функции
Вы теперь можете добавлять модификатор
static
к локальным функциям, чтобы убедиться, что локальная функция не включает (не ссылается) на переменные из обрамляющего её блока кода. Если это произойдёт, будет выброшено исключение CS8421 "A static local function can't contain a reference to <variable>." ("Статическая локальная функция не может ссылаться на <имя переменной>.")
.Рассмотрим следующий код. Локальная функция
LocalFunction
ссылается на переменную y
, объявленную в обрамляющем её коде (методе M
). Поэтому LocalFunction
не может быть объявлена статической:int M()Следующий код содержит статическую локальную функцию. Она может быть объявлена статической, поскольку она не содержит никаких ссылок на переменные из обрамляющего её кода:
{
int y;
LocalFunction();
return y;
void LocalFunction() => y = 0;
}
int M()Источник: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
{
int y = 5;
int x = 7;
return Add(x, y);
static int Add(int left, int right) => left + right;
}
This media is not supported in your browser
VIEW IN TELEGRAM
День семьдесят седьмой. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
1. Задать Следующее Выражение
Многие знают о контекстном меню
1. Наведите на линию кода, куда вы хотите переместить жёлтую стрелку.
2. Зажмите
3. Нажмите на иконку, и жёлтая стрелка переместится на эту строку.
4. Это будет выражением, которое выполнится на следующем шаге или при продолжении отладки (
Отладка в Visual Studio. Малоизвестные трюки
1. Задать Следующее Выражение
Многие знают о контекстном меню
Set Next Statement
(Ctrl+Shift+F10
) – задать следующее выражение, которое перемещает жёлтую стрелку на нужную строку кода. Вы также можете перетащить её вверх или вниз с помощью мыши. Но начиная с Visual Studio 2017 версии 15.3 есть другой способ. 1. Наведите на линию кода, куда вы хотите переместить жёлтую стрелку.
2. Зажмите
CTRL
и заметьте, что зелёная иконка Run to Click
(Выполнить до этого места) меняется на жёлтую Set Next Statement
.3. Нажмите на иконку, и жёлтая стрелка переместится на эту строку.
4. Это будет выражением, которое выполнится на следующем шаге или при продолжении отладки (
F5
).День семьдесят восьмой. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
2. Прерывание при смене значения
У вас бывали ситуации при отладке, когда вы смотрите на значение свойства в одной точке прерывания, а при переходе к другой точке, значение внезапно меняется? Можно поставить прерывание в мутаторе (
1. В точке останова с интересующим экземпляром, щёлкните правой кнопкой на объект и выберите "
2. Перейдите в мутатор нужного вам свойства и добавьте условие прерывания "
3. Продолжите отладку (
4. В стеке вызовов (
Замечание: Object ID ссылается на адрес в памяти, поэтому он изменяется в каждой сессии отладки. Поэтому вам придётся пересоздавать object ID каждый раз. Обработчик ($1) не изменится, поэтому точку останова можно оставить как есть.
Отладка в Visual Studio. Малоизвестные трюки
2. Прерывание при смене значения
У вас бывали ситуации при отладке, когда вы смотрите на значение свойства в одной точке прерывания, а при переходе к другой точке, значение внезапно меняется? Можно поставить прерывание в мутаторе (
set
) свойства класса, но тогда оно будет возникать для всех экземпляров этого типа. А вам нужен только один проблемный экземпляр. Вы можете использовать Object ID
и условные прерывания, чтобы сузить проблемную область.1. В точке останова с интересующим экземпляром, щёлкните правой кнопкой на объект и выберите "
Make Object ID
". Это даст вам обработчик объекта по ссылке "$1
".2. Перейдите в мутатор нужного вам свойства и добавьте условие прерывания "
this == $1
".3. Продолжите отладку (
F5
), и теперь она остановится при изменении свойства этого экземпляра.4. В стеке вызовов (
Call Stack
) нажмите дважды на предпоследний пункт. Это перенесёт вас в строку кода, изменяющую значение свойства выбранного вами экземпляра.Замечание: Object ID ссылается на адрес в памяти, поэтому он изменяется в каждой сессии отладки. Поэтому вам придётся пересоздавать object ID каждый раз. Обработчик ($1) не изменится, поэтому точку останова можно оставить как есть.
👍3
День семьдесят девятый. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
3. Переприкрепление К Процессу
Иногда при разработке приложения вы не можете просто начать его отладку через
Когда вы откроете диалог Прикрепить к Процессу (
После успешного прикрепления к процессу появится возможность повторного прикрепления к процессу -
Отладчик сначала попробует найти тот же процесс, сопоставив ID и имя процесса. Если он его не найдёт, то поиск продолжится по имени. Если будет найдет один процесс, отладчик прикрепится к нему. Если процессов будет найдено несколько, отладчик покажет диалог
Поддерживается возможность переприкрепления к нескольким процессам. Например, если вы использовали диалог
Источник: https://blogs.msdn.microsoft.com/devops/2017/03/07/reattach-to-process-in-visual-studio-2017/
Отладка в Visual Studio. Малоизвестные трюки
3. Переприкрепление К Процессу
Иногда при разработке приложения вы не можете просто начать его отладку через
F5
. Тогда вы можете выбрать пункт меню Прикрепить к Процессу, чтобы отладить его. Зачастую, чтобы таким образом производить отладку, вам нужно осуществлять прикрепление к процессу несколько раз. В Visual Studio 2017 введена новая опция Reattach to Process
(Shift+Alt+P
), которая позволяет вам начать отладку вашего приложения в один клик, без необходимости проходить через весь диалог прикрепления к процессу каждый раз. Вам всё равно придётся вручную прикрепиться к процессу в первый раз после открытия Visual Studio. Однако в этот диалог добавлен новый поисковый фильтр, чтобы быстрее находить нужное приложение.Когда вы откроете диалог Прикрепить к Процессу (
Attach to Process
) - Ctrl+Alt+P
, фильтр поиска появится в верхней части списка доступных процессов. Введите имя процесса, к которому вы хотите прикрепиться, и выберите его из списка. Фильтр "прилипчивый", то есть значение фильтра сохранится, когда вы снова откроете этот диалог.После успешного прикрепления к процессу появится возможность повторного прикрепления к процессу -
Reattach to Process
(Shift+Alt+P
).Отладчик сначала попробует найти тот же процесс, сопоставив ID и имя процесса. Если он его не найдёт, то поиск продолжится по имени. Если будет найдет один процесс, отладчик прикрепится к нему. Если процессов будет найдено несколько, отладчик покажет диалог
Attach to Process
для выбора нужного.Поддерживается возможность переприкрепления к нескольким процессам. Например, если вы использовали диалог
Attach to Process
для отладки пяти разных процессов в одной сессии отладки, а затем вызвали Reattach to Process
, отладчик снова прикрепится ко всем доступным процессам. Для тех, которые не будут найдены, будет выброшено сообщение об ошибке, что прикрепиться к процессу не удалось и почему. Затем откроется диалог Attach to Process
, чтобы вы смогли вручную выбрать недостающие процессы или нажать отмена и продолжить только с найденными процессами.Источник: https://blogs.msdn.microsoft.com/devops/2017/03/07/reattach-to-process-in-visual-studio-2017/
This media is not supported in your browser
VIEW IN TELEGRAM
День восьмидесятый. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
4. Отображение Потоков в Коде
Отладка многопотокового приложения редко бывает простой, но, когда вы можете посмотреть, на какой строке кода находится каждый поток, становится гораздо лучше.
1. На панели отладчика нажмите "Show Threads in Source" ("Показать Потоки в Коде").
2. В полоске с точками останова появится иконка рядом с каждой строкой кода, на которой остановился хотя бы один поток.
3. Наведите курсор на иконку потока, чтобы увидеть идентификаторы и имена всех потоков, которые остановились на этой строке.
4. Щёлкните правой кнопкой на потоке, чтобы увидеть все доступные действия, вроде остановки потока или выбора активного потока.
Заметьте: Эта функциональность сказывается на производительности и снижает скорость отладки. Рекомендуется отключать её, когда вы её не используете.
Отладка в Visual Studio. Малоизвестные трюки
4. Отображение Потоков в Коде
Отладка многопотокового приложения редко бывает простой, но, когда вы можете посмотреть, на какой строке кода находится каждый поток, становится гораздо лучше.
1. На панели отладчика нажмите "Show Threads in Source" ("Показать Потоки в Коде").
2. В полоске с точками останова появится иконка рядом с каждой строкой кода, на которой остановился хотя бы один поток.
3. Наведите курсор на иконку потока, чтобы увидеть идентификаторы и имена всех потоков, которые остановились на этой строке.
4. Щёлкните правой кнопкой на потоке, чтобы увидеть все доступные действия, вроде остановки потока или выбора активного потока.
Заметьте: Эта функциональность сказывается на производительности и снижает скорость отладки. Рекомендуется отключать её, когда вы её не используете.
This media is not supported in your browser
VIEW IN TELEGRAM
День восемьдесят первый. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
4. Проход по шагам внутри одного потока
Как часто при отладке многопотокового кода вы останавливаетесь на точке, делаете шаг и внезапно останавливаетесь в другом потоке? Это происходит из-за того, что точка останова установлена и последовательно достигается разными потоками. По умолчанию отладчик будет останавливаться на ней каждый раз, когда её достигает. При выполнении шага все потоки возобновляются, и один из них достигает точки останова перед тем, как завершается шаг в текущем потоке. В следующий раз попробуйте следующее:
1. Деактивируйте или удалите точку останова, на которой останавливается другой поток.
2. Продолжите выполнение - Continue (F5)
3. Проследите как ваш изначальный шаг в первом потоке завершается и теперь он в текущем контексте отладки.
5. Поскольку ваши точки останова удалены или неактивны, вы можете продолжить отладку по шагам в единственном потоке без прерываний.
Отладка в Visual Studio. Малоизвестные трюки
4. Проход по шагам внутри одного потока
Как часто при отладке многопотокового кода вы останавливаетесь на точке, делаете шаг и внезапно останавливаетесь в другом потоке? Это происходит из-за того, что точка останова установлена и последовательно достигается разными потоками. По умолчанию отладчик будет останавливаться на ней каждый раз, когда её достигает. При выполнении шага все потоки возобновляются, и один из них достигает точки останова перед тем, как завершается шаг в текущем потоке. В следующий раз попробуйте следующее:
1. Деактивируйте или удалите точку останова, на которой останавливается другой поток.
2. Продолжите выполнение - Continue (F5)
3. Проследите как ваш изначальный шаг в первом потоке завершается и теперь он в текущем контексте отладки.
5. Поскольку ваши точки останова удалены или неактивны, вы можете продолжить отладку по шагам в единственном потоке без прерываний.
День восемьдесят второй. #Оффтоп
Понимаю, что, наверное, начинают надоедать однообразные посты о трюках, советах и новинках ещё не вышедшего С# 8. Но ничего не могу поделать. Застрял на нескольких главах Рихтера про сборщик мусора и домены приложения. Интересно, но довольно занудно и длинно написано. Кроме того, сборщик мусора - обширная и достаточно сложная система, что не позволяет хоть как-нибудь сжать 60-страничное содержание главы и уместить его даже в несколько постов. Да и такие сильно технические детали, если и могут быть интересны, то скорее чисто теоретически. Уверен, что 99% разработчиков за всю карьеру не придётся ни разу каким-либо образом вмешиваться в механизм сборщика мусора. Хотя, возможно, я ошибаюсь.
В общем, просто хотел обозначить, что процесс обучения и подготовки к экзамену продолжается, посты из серии "Заметки на полях" ещё будут.
А пока могу порекомендовать серию лекций на YouTube об алгоритмах сортировки от CodeBlog. Сегодня в 20:00 первая лекция про пузырьковую сортировку https://www.youtube.com/watch?v=LxliVjZo1Nc
Понимаю, что, наверное, начинают надоедать однообразные посты о трюках, советах и новинках ещё не вышедшего С# 8. Но ничего не могу поделать. Застрял на нескольких главах Рихтера про сборщик мусора и домены приложения. Интересно, но довольно занудно и длинно написано. Кроме того, сборщик мусора - обширная и достаточно сложная система, что не позволяет хоть как-нибудь сжать 60-страничное содержание главы и уместить его даже в несколько постов. Да и такие сильно технические детали, если и могут быть интересны, то скорее чисто теоретически. Уверен, что 99% разработчиков за всю карьеру не придётся ни разу каким-либо образом вмешиваться в механизм сборщика мусора. Хотя, возможно, я ошибаюсь.
В общем, просто хотел обозначить, что процесс обучения и подготовки к экзамену продолжается, посты из серии "Заметки на полях" ещё будут.
А пока могу порекомендовать серию лекций на YouTube об алгоритмах сортировки от CodeBlog. Сегодня в 20:00 первая лекция про пузырьковую сортировку https://www.youtube.com/watch?v=LxliVjZo1Nc
This media is not supported in your browser
VIEW IN TELEGRAM
День восемьдесят третий. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
6. Определение Значения Функции без Побочных Эффектов
У вас бывали случаи, когда вы вводили выражение в окно Watch или Immediate, чтобы оценить их значение, а потом вам приходилось сталкиваться с побочными эффектами, потому что статус приложения изменился? Обычно это случается, если выражение вызывает функцию, которая приводит к побочным эффектам (изменяет статус приложения). Это может быть не страшно, если вы об этом знаете, а что, если нет? Вот как оценить значение выражения в C# без риска испортить остальную программу.
1. Добавьте "
2. Это приведёт к интерпретации выражения в отдельной «песочнице», не затрагивая основное приложение.
3. Если выражение не может быть интерпретировано таким образом, вы получите сообщение об ошибке.
4. Если вы уверены, что хотите оценить выражение всё равно, уберите модификатор "
Отладка в Visual Studio. Малоизвестные трюки
6. Определение Значения Функции без Побочных Эффектов
У вас бывали случаи, когда вы вводили выражение в окно Watch или Immediate, чтобы оценить их значение, а потом вам приходилось сталкиваться с побочными эффектами, потому что статус приложения изменился? Обычно это случается, если выражение вызывает функцию, которая приводит к побочным эффектам (изменяет статус приложения). Это может быть не страшно, если вы об этом знаете, а что, если нет? Вот как оценить значение выражения в C# без риска испортить остальную программу.
1. Добавьте "
, nse
" (означает “No Side Effects” – Без Побочных Эффектов) после каждого выражения.2. Это приведёт к интерпретации выражения в отдельной «песочнице», не затрагивая основное приложение.
3. Если выражение не может быть интерпретировано таким образом, вы получите сообщение об ошибке.
4. Если вы уверены, что хотите оценить выражение всё равно, уберите модификатор "
, nse
" и попробуйте снова.This media is not supported in your browser
VIEW IN TELEGRAM
День восемьдесят четвёртый. #TipsAndTricks
Отладка в Visual Studio. Малоизвестные трюки
7. Стеки вызовов для всех потоков
Когда есть много потоков, есть и много стеков вызовов. Вам может потребоваться проверить их все, чтобы понять состояние приложения. Вы всегда можете посмотреть на визуальное отображение стека вызовов каждого потока, используя окно Параллельные Стеки (Parallel Stacks) -
1. Откройте окно Command (
2. Введите "
3. Вы также можете использовать популярную команду из WinDBG – "
4. Теперь все потоки со своими стеками вызовов выведены в окне Command.
Отладка в Visual Studio. Малоизвестные трюки
7. Стеки вызовов для всех потоков
Когда есть много потоков, есть и много стеков вызовов. Вам может потребоваться проверить их все, чтобы понять состояние приложения. Вы всегда можете посмотреть на визуальное отображение стека вызовов каждого потока, используя окно Параллельные Стеки (Parallel Stacks) -
Debug > Windows > Parallel Stacks
. Также в окне Command можно посмотреть текстовое представление стека вызовов каждого потока, которое можно скопировать и вставить.1. Откройте окно Command (
View > Other Windows > Command Window
).2. Введите "
Debug.ListCallStacks –AllThreads
"3. Вы также можете использовать популярную команду из WinDBG – "
~*k
"4. Теперь все потоки со своими стеками вызовов выведены в окне Command.