День пятисотый.
Вот и добрались мы с вами до небольшого юбилея. 500 дней подряд я выкладываю посты о том, что мне показалось интересным в мире изучения .NET. Большое спасибо, что читаете и огромное спасибо всем, кто комментирует, предлагает темы, исправляет неточности в постах.
В данный момент я продолжаю подготовку к экзамену 70-486 для получения сертификата MCSA: Web Applications, поэтому большая часть времени (помимо работы и подбора материала для постов) занята этим. Дальше я планирую поглубже окунуться в .NET5, Blazor и WebAssembly. Я недавно публиковал пост на эту тему.
У меня возникла одна идея, но прежде хочу узнать ваше мнение. Осенью выходит .NET5. Нет лучше способа опробовать его, чем практика. У меня есть идея создания полноценного веб приложения на .NET5, Blazor (возможно добавить API) и развёртывания в сервисах Azure (раз уж мы тут про Microsoft, то надо идти до конца))). Приложение будет касаться изучения .NET и программирования вообще. В двух словах – это организованный справочник источников для изучения программирования. Пока не буду вдаваться в детали, я сам ещё полноценную концепцию не продумал.
Собственно, поэтому у меня к вам такой вопрос. Есть ли среди моих подписчиков те, кому в образовательных целях было бы интересно поучаствовать в опенсорс проекте? Понимаю, что это звучит, типа, я ищу бесплатную рабочую силу. Но давайте объясню, как я это вижу. Мы как разработчики постоянно учимся. Это одно из требований профессии. Однако на работе не всегда удаётся учиться и практиковать то, что тебе интересно. Часто в корпоративных системах используются не самые новые версии языка и фреймворков. Часто отдельный разработчик отвечает только за что-то одно: написание модулей, тестирование, фронтенд, - и иногда эти области не пересекаются. Я предлагаю (только тем, кому это интересно) вместе создать приложение с нуля (продумывание функционала, проектирование подсистем, модулей, написание кода, тестов, CI/CD, вотэтовсё) на передовой на данный момент технологии. При этом каждый сможет заняться тем, что ему интересно, поделиться опытом или получить опыт в процессе. Никаких сроков, дедлайнов или обязаловок, всё исключительно по желанию и в свободное от основной деятельности время.
Да, понимаю, что звучит несколько утопично. В принципе, идея взята вот из этого совета. В общем, подумайте на досуге))) Подробности ближе к осени. А пока я хотел бы узнать, в принципе эта идея кому-нибудь интересна, и, если да, в чём вы можете поделиться опытом. Обсудить можем в чате.
Вот и добрались мы с вами до небольшого юбилея. 500 дней подряд я выкладываю посты о том, что мне показалось интересным в мире изучения .NET. Большое спасибо, что читаете и огромное спасибо всем, кто комментирует, предлагает темы, исправляет неточности в постах.
В данный момент я продолжаю подготовку к экзамену 70-486 для получения сертификата MCSA: Web Applications, поэтому большая часть времени (помимо работы и подбора материала для постов) занята этим. Дальше я планирую поглубже окунуться в .NET5, Blazor и WebAssembly. Я недавно публиковал пост на эту тему.
У меня возникла одна идея, но прежде хочу узнать ваше мнение. Осенью выходит .NET5. Нет лучше способа опробовать его, чем практика. У меня есть идея создания полноценного веб приложения на .NET5, Blazor (возможно добавить API) и развёртывания в сервисах Azure (раз уж мы тут про Microsoft, то надо идти до конца))). Приложение будет касаться изучения .NET и программирования вообще. В двух словах – это организованный справочник источников для изучения программирования. Пока не буду вдаваться в детали, я сам ещё полноценную концепцию не продумал.
Собственно, поэтому у меня к вам такой вопрос. Есть ли среди моих подписчиков те, кому в образовательных целях было бы интересно поучаствовать в опенсорс проекте? Понимаю, что это звучит, типа, я ищу бесплатную рабочую силу. Но давайте объясню, как я это вижу. Мы как разработчики постоянно учимся. Это одно из требований профессии. Однако на работе не всегда удаётся учиться и практиковать то, что тебе интересно. Часто в корпоративных системах используются не самые новые версии языка и фреймворков. Часто отдельный разработчик отвечает только за что-то одно: написание модулей, тестирование, фронтенд, - и иногда эти области не пересекаются. Я предлагаю (только тем, кому это интересно) вместе создать приложение с нуля (продумывание функционала, проектирование подсистем, модулей, написание кода, тестов, CI/CD, вотэтовсё) на передовой на данный момент технологии. При этом каждый сможет заняться тем, что ему интересно, поделиться опытом или получить опыт в процессе. Никаких сроков, дедлайнов или обязаловок, всё исключительно по желанию и в свободное от основной деятельности время.
Да, понимаю, что звучит несколько утопично. В принципе, идея взята вот из этого совета. В общем, подумайте на досуге))) Подробности ближе к осени. А пока я хотел бы узнать, в принципе эта идея кому-нибудь интересна, и, если да, в чём вы можете поделиться опытом. Обсудить можем в чате.
Интересна ли вам идея учебного проекта и в какой области вы можете поделиться опытом (выберите наиболее интересную вам):
Anonymous Poll
26%
Да, проектирование
41%
Да, написание кода
4%
Да, написание тестов
3%
Да, разработка UI
14%
Да, создание API
2%
Да, развёртывание
1%
Да, управление проектом
9%
Не интересно
День пятьсот первый. #MoreEffectiveCSharp
13. Предпочитайте Реализацию Интерфейсов Наследованию
Абстрактные базовые классы предоставляют общего предка для иерархии классов. Интерфейс описывает группу связанных методов, содержащих функционал, который должен быть реализован типом. У каждого подхода своё применение, и они не взаимозаменяемы. Интерфейсы - это способ объявления контракта. Абстрактные базовые классы предоставляют общую абстракцию для набора связанных типов. Наследование означает «является» (описывает, что такое объект), а интерфейс означает «ведёт себя как» (описание одного из поведений объекта).
Особенности интерфейсов:
1. Определяют многократно используемое поведение.
2. Могут быть параметром или возвращаемым значением.
3. Могут быть реализованы несвязанными типами.
4. Другим разработчикам легче реализовать интерфейс, чем наследовать от созданного вами базового класса.
5. Вы не можете обеспечить реализацию методов в интерфейсе. Однако можно создать методы расширения для него. Они будут частью любого типа, который реализует интерфейс.
6. Добавление нового члена к интерфейсу сломает все классы, которые его реализуют. Каждый разработчик должен будет обновить тип, чтобы включить новый член. В C#8 в интерфейсе можно определить реализацию по умолчанию, но этот приём нужно использовать с осторожностью. Если вы обнаружите, что вам нужно добавить функциональность в интерфейс, создайте новый и наследуйте от существующего интерфейса.
Особенности абстрактных базовых классов:
- могут предоставлять некоторую реализацию для производных типов в дополнение к описанию общего поведения, обеспечивая общее повторное использование реализации.
- при добавлении нового метода в базовый класс, все производные классы автоматически и неявно обновляются.
Выбор между абстрактным базовым классом и интерфейсом - это вопрос о том, как лучше поддерживать абстракции с течением времени. Интерфейсы фиксированы, а базовые классы могут быть расширены.
Интерфейсы как параметры методов
Рассмотрим два метода:
Интерфейсы как возвращаемые значения
Допустим, ваш класс имеет открытый метод, который возвращает коллекцию объектов:
1. Если вы захотите изменить тип возвращаемого значения со списка на массив или сортированный список, это нарушит код, т.к. это изменит открытый интерфейс вашего класса. Такое изменение заставляет вас делать гораздо больше изменений в системе, чем необходимо: вам нужно будет поменять все места, где происходит обращение к этому методу.
2. Вторая проблема в том, что
Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 14.
13. Предпочитайте Реализацию Интерфейсов Наследованию
Абстрактные базовые классы предоставляют общего предка для иерархии классов. Интерфейс описывает группу связанных методов, содержащих функционал, который должен быть реализован типом. У каждого подхода своё применение, и они не взаимозаменяемы. Интерфейсы - это способ объявления контракта. Абстрактные базовые классы предоставляют общую абстракцию для набора связанных типов. Наследование означает «является» (описывает, что такое объект), а интерфейс означает «ведёт себя как» (описание одного из поведений объекта).
Особенности интерфейсов:
1. Определяют многократно используемое поведение.
2. Могут быть параметром или возвращаемым значением.
3. Могут быть реализованы несвязанными типами.
4. Другим разработчикам легче реализовать интерфейс, чем наследовать от созданного вами базового класса.
5. Вы не можете обеспечить реализацию методов в интерфейсе. Однако можно создать методы расширения для него. Они будут частью любого типа, который реализует интерфейс.
6. Добавление нового члена к интерфейсу сломает все классы, которые его реализуют. Каждый разработчик должен будет обновить тип, чтобы включить новый член. В C#8 в интерфейсе можно определить реализацию по умолчанию, но этот приём нужно использовать с осторожностью. Если вы обнаружите, что вам нужно добавить функциональность в интерфейс, создайте новый и наследуйте от существующего интерфейса.
Особенности абстрактных базовых классов:
- могут предоставлять некоторую реализацию для производных типов в дополнение к описанию общего поведения, обеспечивая общее повторное использование реализации.
- при добавлении нового метода в базовый класс, все производные классы автоматически и неявно обновляются.
Выбор между абстрактным базовым классом и интерфейсом - это вопрос о том, как лучше поддерживать абстракции с течением времени. Интерфейсы фиксированы, а базовые классы могут быть расширены.
Интерфейсы как параметры методов
Рассмотрим два метода:
public static void Print<T>(IEnumerable<T> col) {Любой тип, который поддерживает
foreach (T o in col)
Console.WriteLine(o);
}
public static void Print(MyCollection col) {
foreach (var o in col)
Console.WriteLine(o);
}
IEnumerable<T>
(List<T>
, SortedList<T>
, любой массив и результаты любого запроса LINQ), может использовать первый метод. Второй метод гораздо менее пригоден для повторного использования. Использование интерфейсов в качестве типов параметров метода гораздо более универсально и намного проще для повторного использования.Интерфейсы как возвращаемые значения
Допустим, ваш класс имеет открытый метод, который возвращает коллекцию объектов:
public List<SomeClass> DataSequence => sequence;Это создаёт сразу две проблемы:
private List<SomeClass> sequence = new List<SomeClass>();
1. Если вы захотите изменить тип возвращаемого значения со списка на массив или сортированный список, это нарушит код, т.к. это изменит открытый интерфейс вашего класса. Такое изменение заставляет вас делать гораздо больше изменений в системе, чем необходимо: вам нужно будет поменять все места, где происходит обращение к этому методу.
2. Вторая проблема в том, что
List<T>
предоставляет множество методов для изменения содержащихся в нём данных. Клиенты вашего класса смогут удалять, изменять или даже заменять элементы списка. Почти наверняка вы этого не хотите. К счастью, вы можете ограничить их возможности, вернув вместо ссылки на некоторый внутренний объект интерфейс IEnumerable<SomeClass>
. Используя интерфейсы в качестве типа возвращаемого значения, вы можете выбирать, какие методы и свойства для работы с предоставляемыми данными вы хотите открыть для клиентов класса.Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 14.
День пятьсот второй. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
45. Знай Свою IDE
В 1980-х наши среды разработки были, в лучшем случае, немногим полезнее, обычных текстовых редакторов. Подсветка синтаксиса, которую мы сейчас считаем само собой разумеющейся, была не всем доступной роскошью. Инструменты форматирования кода обычно были сторонними продуктами, которые нужно было запускать, чтобы исправить отступы. Отладчики были также отдельными программами, запускаемыми для пошагового выполнения кода со множеством загадочных нажатий клавиш.
В 1990-х компании начали осознавать потенциальную пользу, которую они могли бы извлечь, предоставляя программистам лучшие и более полезные инструменты. Интегрированная среда разработки (IDE) объединила функции редактирования кода с компилятором, отладчиком, инструментами форматирования и другими полезными функциями. К тому времени выпадающие меню и мышь также стали популярными, что означало, что разработчикам больше не нужно было изучать загадочные комбинации клавиш, чтобы использовать редактор. Они могли просто выбрать команду из меню.
В 21-м веке IDE стали настолько обычным явлением, что их бесплатно раздают компании, желающие получить долю рынка в других областях. Современная IDE оснащена удивительным набором функций. Мой любимый инструмент - автоматический рефакторинг, особенно извлечение в метод, когда я могу выделить часть кода и преобразовывать его в метод. Инструмент рефакторинга подберёт все параметры, которые необходимо передать, что делает его использование чрезвычайно простым. IDE даже обнаружит другие похожие фрагменты кода, которые также могут быть заменены этим методом, и спросит меня, не хочу ли я их заменить.
Еще одна удивительная особенность современных IDE - возможность применять правила корпоративного стиля. Табы или пробелы, открывающая фигурная скобка в конце объявления или на новой строке… Каков бы ни был принятый стиль в компании, всё, что мне нужно сделать, чтобы следовать ему, это настроить его в моей IDE. Правила стиля также могут использоваться для поиска возможных ошибок.
К сожалению, современные IDE не требуют от нас усилий, чтобы научиться их использовать. Когда я впервые программировал в C на Unix, мне пришлось потратить немало времени на изучение работы редактора vi. Это потраченное время окупилось за годы использования. Я даже набираю черновик этой статьи с помощью vi. Современные IDE имеют очень плавную кривую обучения, что может привести к тому, что мы никогда не выйдем за рамки самого простого использования инструмента.
Мой первый шаг в изучении IDE - запоминание сочетаний клавиш. Так как мои пальцы находятся на клавиатуре, когда я набираю код, нажатие сочетания клавиш не прерывает хода работы, тогда использование мыши заставляет отвлечься, найти мышь, навести курсор, найти нужный пункт меню… Эти отвлечения приводят к ненужным переключениям контекста, снижая производительность. То же правило относится и к навыкам печатания: научитесь слепой печати - вы не пожалеете о потраченном времени. Наконец, у нас много инструментов манипуляции кодом: инструменты рефакторинга, поиска и замены по шаблону, и т.п.
Мы ожидаем, что сантехник, приходящий в наш дом, сможет использовать свой разводной ключ и отвёртки, и знает, как с ними обращаться. Давайте потратим немного времени на изучение того, как повысить эффективность в нашей IDE.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Heinz Kabutz
97 Вещей, Которые Должен Знать Каждый Программист
45. Знай Свою IDE
В 1980-х наши среды разработки были, в лучшем случае, немногим полезнее, обычных текстовых редакторов. Подсветка синтаксиса, которую мы сейчас считаем само собой разумеющейся, была не всем доступной роскошью. Инструменты форматирования кода обычно были сторонними продуктами, которые нужно было запускать, чтобы исправить отступы. Отладчики были также отдельными программами, запускаемыми для пошагового выполнения кода со множеством загадочных нажатий клавиш.
В 1990-х компании начали осознавать потенциальную пользу, которую они могли бы извлечь, предоставляя программистам лучшие и более полезные инструменты. Интегрированная среда разработки (IDE) объединила функции редактирования кода с компилятором, отладчиком, инструментами форматирования и другими полезными функциями. К тому времени выпадающие меню и мышь также стали популярными, что означало, что разработчикам больше не нужно было изучать загадочные комбинации клавиш, чтобы использовать редактор. Они могли просто выбрать команду из меню.
В 21-м веке IDE стали настолько обычным явлением, что их бесплатно раздают компании, желающие получить долю рынка в других областях. Современная IDE оснащена удивительным набором функций. Мой любимый инструмент - автоматический рефакторинг, особенно извлечение в метод, когда я могу выделить часть кода и преобразовывать его в метод. Инструмент рефакторинга подберёт все параметры, которые необходимо передать, что делает его использование чрезвычайно простым. IDE даже обнаружит другие похожие фрагменты кода, которые также могут быть заменены этим методом, и спросит меня, не хочу ли я их заменить.
Еще одна удивительная особенность современных IDE - возможность применять правила корпоративного стиля. Табы или пробелы, открывающая фигурная скобка в конце объявления или на новой строке… Каков бы ни был принятый стиль в компании, всё, что мне нужно сделать, чтобы следовать ему, это настроить его в моей IDE. Правила стиля также могут использоваться для поиска возможных ошибок.
К сожалению, современные IDE не требуют от нас усилий, чтобы научиться их использовать. Когда я впервые программировал в C на Unix, мне пришлось потратить немало времени на изучение работы редактора vi. Это потраченное время окупилось за годы использования. Я даже набираю черновик этой статьи с помощью vi. Современные IDE имеют очень плавную кривую обучения, что может привести к тому, что мы никогда не выйдем за рамки самого простого использования инструмента.
Мой первый шаг в изучении IDE - запоминание сочетаний клавиш. Так как мои пальцы находятся на клавиатуре, когда я набираю код, нажатие сочетания клавиш не прерывает хода работы, тогда использование мыши заставляет отвлечься, найти мышь, навести курсор, найти нужный пункт меню… Эти отвлечения приводят к ненужным переключениям контекста, снижая производительность. То же правило относится и к навыкам печатания: научитесь слепой печати - вы не пожалеете о потраченном времени. Наконец, у нас много инструментов манипуляции кодом: инструменты рефакторинга, поиска и замены по шаблону, и т.п.
Мы ожидаем, что сантехник, приходящий в наш дом, сможет использовать свой разводной ключ и отвёртки, и знает, как с ними обращаться. Давайте потратим немного времени на изучение того, как повысить эффективность в нашей IDE.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Heinz Kabutz
День пятьсот третий. #ЧтоНовенького
В Microsoft объявили о выходе .NET 5.0 Preview 5. Эта предварительная версия описана как «небольшой набор новых функций и улучшений производительности», так как большая часть функционала, запланированного под .NET 5, была выпущена в Preview 4 в прошлом месяце. Из особенностей Preview 5 можно выделить обновления в ASP.NET и Entity Framework.
В ASP.NET Core:
- Обновляемые конечные точки в конфигурации Kestrel
Kestrel теперь имеет возможность отслеживать изменения в конфигурации, передаваемой через
В Entity Framework Core 5.0
1. Параметры сортировки (collations) базы данных
Параметры сортировки теперь можно указать в модели EF, и они будут указаны в миграции.
- Для всей базы данных:
Теперь из командной строки в метод
3. Сохраняемые вычисляемые столбцы
Большинство баз данных позволяют хранить вычисляемые значения в столбцах. Хотя это занимает место на диске, вычисляемый столбец вычисляется только один раз при обновлении, а не каждый раз, когда извлекается его значение. Это также позволяет индексировать столбец в некоторых базах данных. EF Core 5.0 позволяет конфигурировать вычисляемые столбцы как сохраняемые:
Запросы без отслеживания теперь можно настроить для разрешения идентификатора. Например, следующий запрос создаст новый экземпляр
Источники:
- https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-preview-5/
- https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-5-0-preview-5/
В Microsoft объявили о выходе .NET 5.0 Preview 5. Эта предварительная версия описана как «небольшой набор новых функций и улучшений производительности», так как большая часть функционала, запланированного под .NET 5, была выпущена в Preview 4 в прошлом месяце. Из особенностей Preview 5 можно выделить обновления в ASP.NET и Entity Framework.
В ASP.NET Core:
- Обновляемые конечные точки в конфигурации Kestrel
Kestrel теперь имеет возможность отслеживать изменения в конфигурации, передаваемой через
KestrelServerOptions.Configure
и применять изменения к конечным точкам без необходимости перезапуска приложения.В Entity Framework Core 5.0
1. Параметры сортировки (collations) базы данных
Параметры сортировки теперь можно указать в модели EF, и они будут указаны в миграции.
- Для всей базы данных:
modelBuilder.UseCollation("German_PhoneBook_CI_AS");Это приведёт к следующему коду для SQL Server:
CREATE DATABASE [Test]- Для отдельных столбцов:
COLLATE German_PhoneBook_CI_AS;
modelBuilder-
.Entity<User>()
.Property(e => e.Name)
.UseCollation("German_PhoneBook_CI_AS");
EF.Functions.Collate
для отдельных запросов (с осторожностью, т.к. это может негативно сказаться на производительности):context.Users.Single(e => EF.Functions.Collate(e.Name, "French_CI_AS") == "Jean-Michel Jarre");2. Аргументы управления потоком в IDesignTimeDbContextFactory
Теперь из командной строки в метод
CreateDbContext
объекта IDesignTimeDbContextFactory
можно передавать пользовательские аргументы. Например, указать, что сборка для разработки, в командной строке можно передать пользовательский аргумент (например, dev
):dotnet ef migrations add two --verbose --devЭтот аргумент затем поступит в фабрику, где он может быть использован для управления созданием и инициализацией контекста.
3. Сохраняемые вычисляемые столбцы
Большинство баз данных позволяют хранить вычисляемые значения в столбцах. Хотя это занимает место на диске, вычисляемый столбец вычисляется только один раз при обновлении, а не каждый раз, когда извлекается его значение. Это также позволяет индексировать столбец в некоторых базах данных. EF Core 5.0 позволяет конфигурировать вычисляемые столбцы как сохраняемые:
modelBuilder4. Запросы без отслеживания с разрешением идентификатора
.Entity<User>()
.Property(e => e.SomethingComputed)
.HasComputedColumnSql("my sql", stored: true);
Запросы без отслеживания теперь можно настроить для разрешения идентификатора. Например, следующий запрос создаст новый экземпляр
Blog
для каждой записи из Posts
, даже при том, что экземпляры будут иметь одинаковые первичные ключи:context.Posts.AsNoTracking().Include(e => e.Blog).ToList();Этот запрос можно изменить, чтобы обеспечить создание только одного экземпляра
Blog
:context.Posts.AsNoTracking().PerformIdentityResolution().Include(e => e.Blog).ToList();Обратите внимание, что это полезно только для запросов без отслеживания (
AsNoTracking
).Источники:
- https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-preview-5/
- https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-5-0-preview-5/
День пятьсот пятый. #ЧтоНовенького
Официально выпущен gRPC-Web для .NET
gRPC - это современная высокопроизводительная среда Удаленного Вызова Процедур (RPC). gRPC основан на HTTP/2, Protocol Buffers и других современных стандартах. gRPC является открытым стандартом и поддерживается многими языками программирования, включая .NET.
В настоящее время невозможно реализовать спецификацию gRPC HTTP/2 в браузере, поскольку не существует API браузера с достаточным детальным контролем над запросами. gRPC-Web - это стандартизированный протокол, который решает эту проблему и позволяет использовать gRPC в браузере. gRPC-Web привносит многие современные функции gRPC, такие как небольшие двоичные сообщения и API Contract First, в современные приложения для браузеров.
Новые возможности с gRPC-Web
gRPC-Web разработан, чтобы сделать gRPC доступным в большем количестве сценариев. К ним относятся:
1. Вызов приложений ASP.NET Core gRPC из браузера - API браузера не могут вызывать gRPC HTTP/2. gRPC-Web предлагает совместимую альтернативу:
- JavaScript SPA
- Приложения .NET Blazor Web Assembly
2. Размещение приложений ASP.NET Core gRPC в IIS и Службе Приложений Azure - Некоторые серверы, такие как IIS и Служба Приложений Azure, в настоящее время не могут размещать службы gRPC. Пока над этим активно работают, gRPC-Web предлагает альтернативу, которая сегодня работает в любой среде.
3. Вызовы gRPC с платформ, отличных от .NET Core - HttpClient не поддерживает HTTP/2 на платформах .NET. gRPC-Web может использоваться для вызова сервисов gRPC из Blazor и Xamarin.
gRPC-Web – это комплексное решение для разработчиков при использовании в приложениях Blazor WebAssembly. Инструментарий gRPC не только автоматически генерирует строго типизированные клиенты для вызова служб gRPC из приложений Blazor, но и предлагает значительные преимущества в производительности по сравнению с JSON. Повышение производительности происходит благодаря эффективной двоичной сериализации gRPC по сравнению с традиционным текстовым JSON.
Попробуйте gRPC-Web с ASP.NET Core
- Новичкам в gRPC подойдёт руководство «Создание Клиента и Сервера gRPC в ASP.NET Core».
- Для готовых приложений посмотрите статью «Использование gRPC в браузерных приложениях».
- Пример приложения, использующего gRPC-Web.
gRPC-Web для .NET доступна в NuGet пакетах:
-
-
Источник: https://devblogs.microsoft.com/aspnet/grpc-web-for-net-now-available/
Официально выпущен gRPC-Web для .NET
gRPC - это современная высокопроизводительная среда Удаленного Вызова Процедур (RPC). gRPC основан на HTTP/2, Protocol Buffers и других современных стандартах. gRPC является открытым стандартом и поддерживается многими языками программирования, включая .NET.
В настоящее время невозможно реализовать спецификацию gRPC HTTP/2 в браузере, поскольку не существует API браузера с достаточным детальным контролем над запросами. gRPC-Web - это стандартизированный протокол, который решает эту проблему и позволяет использовать gRPC в браузере. gRPC-Web привносит многие современные функции gRPC, такие как небольшие двоичные сообщения и API Contract First, в современные приложения для браузеров.
Новые возможности с gRPC-Web
gRPC-Web разработан, чтобы сделать gRPC доступным в большем количестве сценариев. К ним относятся:
1. Вызов приложений ASP.NET Core gRPC из браузера - API браузера не могут вызывать gRPC HTTP/2. gRPC-Web предлагает совместимую альтернативу:
- JavaScript SPA
- Приложения .NET Blazor Web Assembly
2. Размещение приложений ASP.NET Core gRPC в IIS и Службе Приложений Azure - Некоторые серверы, такие как IIS и Служба Приложений Azure, в настоящее время не могут размещать службы gRPC. Пока над этим активно работают, gRPC-Web предлагает альтернативу, которая сегодня работает в любой среде.
3. Вызовы gRPC с платформ, отличных от .NET Core - HttpClient не поддерживает HTTP/2 на платформах .NET. gRPC-Web может использоваться для вызова сервисов gRPC из Blazor и Xamarin.
gRPC-Web – это комплексное решение для разработчиков при использовании в приложениях Blazor WebAssembly. Инструментарий gRPC не только автоматически генерирует строго типизированные клиенты для вызова служб gRPC из приложений Blazor, но и предлагает значительные преимущества в производительности по сравнению с JSON. Повышение производительности происходит благодаря эффективной двоичной сериализации gRPC по сравнению с традиционным текстовым JSON.
Попробуйте gRPC-Web с ASP.NET Core
- Новичкам в gRPC подойдёт руководство «Создание Клиента и Сервера gRPC в ASP.NET Core».
- Для готовых приложений посмотрите статью «Использование gRPC в браузерных приложениях».
- Пример приложения, использующего gRPC-Web.
gRPC-Web для .NET доступна в NuGet пакетах:
-
Grpc.AspNetCore.Web
- добавляет поддержку gRPC-Web в службу ASP.NET Core gRPC.-
Grpc.Net.Client.Web
– позволяет осуществлять вызовы конечных точек gRPC-Web из .NET.Источник: https://devblogs.microsoft.com/aspnet/grpc-web-for-net-now-available/
День пятьсот шестой. #MoreEffectiveCSharp
Новый Паттерн для Логирования Исключений
Логируйте исключения из фильтра исключений, а не из блока catch.
Современные системы логирования поддерживают расширенные контекстные журналы. Вы можете добавлять поля данных в сообщения журнала, а затем использовать их при отладке. Например, отфильтровать журнал по диапазону кодов HTTP или показать только ошибки
Помимо этого, современные системы поддерживают области логирования (см. BeginScope), что позволяет добавлять дополнительную информацию к сообщению в лог из разных частей метода, которая будет записана при вызове метода записи в журнал.
Большинство методов не логгируют исключения, они выбрасывают их вверх по стеку, где исключение регистрируется на более высоком уровне. Проблема этого подхода заключается в том, что область логгирования теряется после разворачивания стека:
Решение
Фильтры исключений выполняется там, где выбрасывается исключение, а не там, где оно перехватывается. Это происходит до разворачивания стека, поэтому область логирования сохраняется.
Фильтр исключений должен возвращать булево значение, указывающее, подходит ли блок
1.
Новый Паттерн для Логирования Исключений
Логируйте исключения из фильтра исключений, а не из блока catch.
Современные системы логирования поддерживают расширенные контекстные журналы. Вы можете добавлять поля данных в сообщения журнала, а затем использовать их при отладке. Например, отфильтровать журнал по диапазону кодов HTTP или показать только ошибки
FileNotFound
у пользователя Steve
.Помимо этого, современные системы поддерживают области логирования (см. BeginScope), что позволяет добавлять дополнительную информацию к сообщению в лог из разных частей метода, которая будет записана при вызове метода записи в журнал.
Большинство методов не логгируют исключения, они выбрасывают их вверх по стеку, где исключение регистрируется на более высоком уровне. Проблема этого подхода заключается в том, что область логгирования теряется после разворачивания стека:
try {
MyMethod();
}
catch (Exception e) {
logger.LogError(e, "");
…
}
Когда генерируется исключение, среда выполнения будет искать в стеке соответствующий обработчик. Cтек разворачивается до найденной точки и выполняется блок catch
. Таким образом, дополнительная информация в области логирования, добавленная в методе MyMethod
, будет потеряна при логировании исключения из блока catch
.Решение
Фильтры исключений выполняется там, где выбрасывается исключение, а не там, где оно перехватывается. Это происходит до разворачивания стека, поэтому область логирования сохраняется.
Фильтр исключений должен возвращать булево значение, указывающее, подходит ли блок
catch
под фильтр. В нашем случае логирование - просто побочный эффект, который не влияет на соответствие блока catch
фильтру. Определим два метода, возвращающие true
или false
в зависимости от того, нужно нам «проглотить» исключение, либо выбросить его выше по стеку:1.
Rethrow
можно использовать, когда catch
не содержит ничего, кроме throw;
. В таком случае Rethrow
логгирует исключение, вернёт false, блок catch не выполнится, а среда выполнения продолжит искать обработчик выше по стеку:try {
MyMethod();
}
catch (Exception e) when
(Rethrow(()=>logger.LogError(e, ""))
{
throw;
}
public static bool Rethrow(Action action) {
action();
return false;
}
2. Другой сценарий, когда catch
обрабатывает исключение. В этом случае метод Handle
логирует исключение, вернёт true
, и исключение будет обработано в блоке catch
:try {
MyMethod();
}
catch (Exception e) when
(Handle(()=>logger.LogError(e, ""))
{
// обработка исключения
}
public static bool Handle(Action action) {
action();
return true;
}
Источник: https://blog.stephencleary.com/2020/06/a-new-pattern-for-exception-logging.htmlДень пятьсот седьмой. #CSharp9
C# 9: На Пути к Поддержке Сценариев
Одной из определяющих характеристик языков «сценариев» является то, что им не нужен шаблон. Самой первой строкой файла могут быть объявления и операторы. Тогда как в C# или Java требуется некоторый метод
Мэдс Торгерсен из Microsoft предлагает реализовать эту возможность в C# 9. Операторы и функции верхнего уровня можно будет не включать в метод
Компилятор C # в настоящее время понимает диалект языка, используемого для различных сценариев и интерактивных целей. На этом диалекте операторы могут быть написаны на верхнем уровне (без включения в тело методов), а невиртуальные члены могут быть написаны на верхнем уровне (без включения в объявление типа).
В настоящее время версия C# для сценариев используется не очень интенсивно, но Торгерсен предсказывает, что это изменится в будущем: «Помимо Try.NET, сценарии также набирают популярность в обработке данных и машинном обучении, и там сценарные языки выигрывают от непосредственного режима работы с живыми данными.»
Есть несколько сценариев реализации этого функционала, наиболее вероятный из которых следующий. Операторы будет разрешено размещать перед объявлением пространства имен. Любые такие операторы будут скомпилированы в функцию
Содержимое операторов будет определять, как будет выглядеть сгенерированный код. Существует четыре возможности в зависимости от того, используется ли
Другой сценарий. Функции могут быть объявлены в пространстве имен или глобально. По умолчанию они будут
Источник: https://www.infoq.com/news/2020/05/CSharp-9-Scripting/
C# 9: На Пути к Поддержке Сценариев
Одной из определяющих характеристик языков «сценариев» является то, что им не нужен шаблон. Самой первой строкой файла могут быть объявления и операторы. Тогда как в C# или Java требуется некоторый метод
Main
, содержащийся внутри класса.Мэдс Торгерсен из Microsoft предлагает реализовать эту возможность в C# 9. Операторы и функции верхнего уровня можно будет не включать в метод
Main
класса Program
.Компилятор C # в настоящее время понимает диалект языка, используемого для различных сценариев и интерактивных целей. На этом диалекте операторы могут быть написаны на верхнем уровне (без включения в тело методов), а невиртуальные члены могут быть написаны на верхнем уровне (без включения в объявление типа).
В настоящее время версия C# для сценариев используется не очень интенсивно, но Торгерсен предсказывает, что это изменится в будущем: «Помимо Try.NET, сценарии также набирают популярность в обработке данных и машинном обучении, и там сценарные языки выигрывают от непосредственного режима работы с живыми данными.»
Есть несколько сценариев реализации этого функционала, наиболее вероятный из которых следующий. Операторы будет разрешено размещать перед объявлением пространства имен. Любые такие операторы будут скомпилированы в функцию
Main
класса Program
. Эта функция будет поддерживать асинхронные операции. Если несколько файлов имеют исполняемые операторы вне пространства имен, произойдет ошибка компилятора. Содержимое операторов будет определять, как будет выглядеть сгенерированный код. Существует четыре возможности в зависимости от того, используется ли
await
или нет, и есть ли оператор return
:static void Main(string[] args)Локальные функции разрешены с использованием обычного синтаксиса.
static int Main(string[] args)
static Task Main(string[] args)
static Task<int> Main(string[] args)
Другой сценарий. Функции могут быть объявлены в пространстве имен или глобально. По умолчанию они будут
internal
, хотя public
также будет разрешён. Потребители увидят, что функция принадлежит непосредственно к пространству имен. Реализовано это будет через частичный класс, оборачивающий элементы как статические члены. Если какой-либо из членов верхнего уровня будет public
, то и класс будет public
и помечен таким образом, чтобы потребляющая сборка знала, что к членам этого класса можно будет обращаться напрямую.Источник: https://www.infoq.com/news/2020/05/CSharp-9-Scripting/
День пятьсот восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
46. Знайте Свои Пределы
Ваши ресурсы ограничены. У вас есть только определённое количество времени и денег, чтобы выполнять свою работу, включая время и деньги, необходимые для обновления ваших знаний, навыков и инструментов. Вы можете работать только с определённым усердием, скоростью и не бесконечно. Ваши инструменты ограничены по мощности. Машины ваших пользователей тем более ограничены по мощности. Таким образом, вы должны знать ограничения своих ресурсов.
Как соблюдать эти ограничения? Знайте свои способности, знайте способности коллег, знайте свой бюджет и знайте свои инструменты. Особенно, как инженер-программист, вы должны знать пространственно-временную сложность ваших структур данных и алгоритмов, а также архитектуру и характеристики производительности ваших систем. Ваша задача - создать оптимальное сочетание программного обеспечения и систем.
Пространственно-временная сложность задается как функция
Анализ сложности измеряется в терминах абстрактной машины, но программное обеспечение работает на реальных машинах. Современные компьютерные системы организованы в виде иерархий физических и виртуальных машин, включая языковые среды выполнения, операционные системы, процессоры, кэш-память, оперативную память, диски и сети.
Ёмкость и скорость обращения к различным хранилищам варьируются на несколько порядков. Кэширование и последовательный доступ интенсивно используются на каждом уровне наших систем, чтобы скрыть эту разницу, но они работают только тогда, когда доступ предсказуем. При частых «промахах кэша» система будет тормозить. Например, чтобы в случайном порядке прочитать все байты жесткого диска, может понадобиться 32 года. А чтобы случайно просмотреть всю оперативную память – 11 минут. Случайный доступ непредсказуем. Исходя из этого, следует помнить, что повторный доступ к уже использовавшимся элементам и последовательный доступ практически всегда работают эффективно.
Алгоритмы и структуры данных различаются по тому, насколько эффективно они используют кэш. Например:
- Линейный поиск хорошо использует последовательный доступ, но требует
- Двоичный поиск отсортированного массива требует только
- Поиск по дереву van Emde Boas также требует
Как выбрать? Только измеряя. Линейный поиск наиболее выгоден для небольших массивов, однако существенно проигрывает при увеличении размера. Алгоритм van Emde Boas выигрывает благодаря предсказуемому доступу к данным.
Источники:
- https://www.oreilly.com/library/view/97-things-every/9780596809515/ Автор оригинала – Greg Colvin
- https://habr.com/ru/post/188010/
97 Вещей, Которые Должен Знать Каждый Программист
46. Знайте Свои Пределы
Ваши ресурсы ограничены. У вас есть только определённое количество времени и денег, чтобы выполнять свою работу, включая время и деньги, необходимые для обновления ваших знаний, навыков и инструментов. Вы можете работать только с определённым усердием, скоростью и не бесконечно. Ваши инструменты ограничены по мощности. Машины ваших пользователей тем более ограничены по мощности. Таким образом, вы должны знать ограничения своих ресурсов.
Как соблюдать эти ограничения? Знайте свои способности, знайте способности коллег, знайте свой бюджет и знайте свои инструменты. Особенно, как инженер-программист, вы должны знать пространственно-временную сложность ваших структур данных и алгоритмов, а также архитектуру и характеристики производительности ваших систем. Ваша задача - создать оптимальное сочетание программного обеспечения и систем.
Пространственно-временная сложность задается как функция
O(f(n))
, которая для n
, определяющего объём входных данных, определяет объём затрачиваемых пространства или времени, при росте n
. Основные уровни сложности для f(n)
включают 1
, log(n)
, n
, nlog(n)
, n^2
, 2^n
и n!
. Как видно из графика этих функций ниже, при росте n
: O(log(n))
растёт намного медленнее, чем O(n)
или O(nlog(n))
, а они - намного медленнее, чем O(n^2)
или O(2^n)
. Как говорит Шон Перент, для доступных значений n
можно выделить три класса сложности: константная, линейная и бесконечная.Анализ сложности измеряется в терминах абстрактной машины, но программное обеспечение работает на реальных машинах. Современные компьютерные системы организованы в виде иерархий физических и виртуальных машин, включая языковые среды выполнения, операционные системы, процессоры, кэш-память, оперативную память, диски и сети.
Ёмкость и скорость обращения к различным хранилищам варьируются на несколько порядков. Кэширование и последовательный доступ интенсивно используются на каждом уровне наших систем, чтобы скрыть эту разницу, но они работают только тогда, когда доступ предсказуем. При частых «промахах кэша» система будет тормозить. Например, чтобы в случайном порядке прочитать все байты жесткого диска, может понадобиться 32 года. А чтобы случайно просмотреть всю оперативную память – 11 минут. Случайный доступ непредсказуем. Исходя из этого, следует помнить, что повторный доступ к уже использовавшимся элементам и последовательный доступ практически всегда работают эффективно.
Алгоритмы и структуры данных различаются по тому, насколько эффективно они используют кэш. Например:
- Линейный поиск хорошо использует последовательный доступ, но требует
O(n)
сравнений.- Двоичный поиск отсортированного массива требует только
O(log(n))
сравнений.- Поиск по дереву van Emde Boas также требует
O(log(n))
сравнений и при этом эффективно использует кэш.Как выбрать? Только измеряя. Линейный поиск наиболее выгоден для небольших массивов, однако существенно проигрывает при увеличении размера. Алгоритм van Emde Boas выигрывает благодаря предсказуемому доступу к данным.
Источники:
- https://www.oreilly.com/library/view/97-things-every/9780596809515/ Автор оригинала – Greg Colvin
- https://habr.com/ru/post/188010/
День пятьсот девятый. #CSharp9
C# 9: Улучшения Частичных Методов для Генераторов Кода
Генераторы исходного кода в C# 9 позволят расширениям компилятора проверять код, а затем вводить дополнительный исходный код во время компиляции. Этот внедрённый код затем включается в ту же компилируемую сборку. Чтобы упростить эту возможность, Microsoft снимает большинство ограничений с частичных методов.
Частичные методы были введены в 2007 году, чтобы расширить возможности генераторов исходного кода. Основная идея в том, что в сгенерированном коде есть заглушки в виде частичных методов. Если разработчик хочет изменить поведение кода, то он может реализовать частичный метод. В противном случае частичный метод, как и любые его вызовы, удаляются.
Теперь поведение изменено. Разработчик определяет, какие частичные методы нужны. Затем генератор исходного кода видит и реализует их, используя комбинацию внешней информации и информации об окружении. Например, генератор исходного кода может комбинировать атрибуты частичного метода со схемой базы данных для генерации SQL кода запроса.
В настоящее время частичные методы имеют несколько ограничений:
- должны возвращать void,
- могут иметь параметры in или ref, но не out,
- неявно являются закрытыми, и поэтому не могут быть виртуальными,
Согласно предложению о расширении частичных методов, эти ограничения будут сняты. Причина этого изменения объясняется так: «Это расширило бы набор сценариев использования генераторов кода, в которых могли бы участвовать частичные методы. Например, регулярное выражение может быть определено с использованием следующего шаблона:
При этом получится вторая категория частичных методов, которые не будут удаляться из кода, но не будут ограничены в том, что вы можете с ними делать. Чтобы различать две категории, предлагается два основных правила:
1. Если
2. Если
Чисто технически эта новая категория частичных методов представляет собой абстрактные методы, потому что они должны быть реализованы. Но поскольку такие методы не обязательно являются виртуальными, в Microsoft решили, что перепрофилирование ключевого слова
Другие члены класса, такие как частичные свойства, частичные конструкторы и частичные операторы, находятся на рассмотрении для C# 10. Поскольку они не являются строго необходимыми для расширения возможностей генераторов кода, вводить их в C# 9 не является критически важным.
Источник: https://www.infoq.com/news/2020/06/CSharp-9-Partial-Methods/
C# 9: Улучшения Частичных Методов для Генераторов Кода
Генераторы исходного кода в C# 9 позволят расширениям компилятора проверять код, а затем вводить дополнительный исходный код во время компиляции. Этот внедрённый код затем включается в ту же компилируемую сборку. Чтобы упростить эту возможность, Microsoft снимает большинство ограничений с частичных методов.
Частичные методы были введены в 2007 году, чтобы расширить возможности генераторов исходного кода. Основная идея в том, что в сгенерированном коде есть заглушки в виде частичных методов. Если разработчик хочет изменить поведение кода, то он может реализовать частичный метод. В противном случае частичный метод, как и любые его вызовы, удаляются.
Теперь поведение изменено. Разработчик определяет, какие частичные методы нужны. Затем генератор исходного кода видит и реализует их, используя комбинацию внешней информации и информации об окружении. Например, генератор исходного кода может комбинировать атрибуты частичного метода со схемой базы данных для генерации SQL кода запроса.
В настоящее время частичные методы имеют несколько ограничений:
- должны возвращать void,
- могут иметь параметры in или ref, но не out,
- неявно являются закрытыми, и поэтому не могут быть виртуальными,
Согласно предложению о расширении частичных методов, эти ограничения будут сняты. Причина этого изменения объясняется так: «Это расширило бы набор сценариев использования генераторов кода, в которых могли бы участвовать частичные методы. Например, регулярное выражение может быть определено с использованием следующего шаблона:
[RegexGenerated("(dog|cat|fish)")]Это даёт разработчику простой декларативный способ использования генераторов кода, а генераторам очень простой набор инструкций для генерации вывода.»
public partial bool IsPetMatch(string input);
При этом получится вторая категория частичных методов, которые не будут удаляться из кода, но не будут ограничены в том, что вы можете с ними делать. Чтобы различать две категории, предлагается два основных правила:
1. Если
partial
указан с явным модификатором доступа (public
, private
и т.д.), то метод должен быть реализован, может возвращать значения и может иметь параметры out
.2. Если
partial
указан без явного модификатора доступа, то метод может быть удалён из кода, должен возвращать void
и не может иметь out
параметров.Чисто технически эта новая категория частичных методов представляет собой абстрактные методы, потому что они должны быть реализованы. Но поскольку такие методы не обязательно являются виртуальными, в Microsoft решили, что перепрофилирование ключевого слова
abstract
только внесёт лишнюю путаницу.Другие члены класса, такие как частичные свойства, частичные конструкторы и частичные операторы, находятся на рассмотрении для C# 10. Поскольку они не являются строго необходимыми для расширения возможностей генераторов кода, вводить их в C# 9 не является критически важным.
Источник: https://www.infoq.com/news/2020/06/CSharp-9-Partial-Methods/
День пятьсот десятый. #ЗаметкиНаПолях
Указатели в C#
Несмотря на то, что в C# 7 добавлены достаточно богатые возможности передачи типов значений по ссылке, иногда требуется использовать небезопасный код и канонические указатели.
Указатель - это переменная, которая содержит адрес хранения значения в памяти. В C# указатели могут быть объявлены только для типов значений.
Указатели объявляются с помощью символа «разыменования»
Оператор
Указатели могут быть объявлены для структур, как в следующем примере:
Основная проблема с использованием указателей в C# в том, что CLR управляет процессом сбора мусора в фоновом режиме. Освобождая память, сборка мусора может изменить расположение объекта без предупреждения и испортить указатель на него. Это может как поставить под угрозу работу программы, так и повлиять на целостность других программ. Из-за этих проблем использование указателей ограничено кодом, который программист явно помечает как «небезопасный» (
Чтобы решить эту проблему, можно объявить указатель в выражении
Указатель может быть объявлен для массива:
Указатели в C#
Несмотря на то, что в C# 7 добавлены достаточно богатые возможности передачи типов значений по ссылке, иногда требуется использовать небезопасный код и канонические указатели.
Указатель - это переменная, которая содержит адрес хранения значения в памяти. В C# указатели могут быть объявлены только для типов значений.
Указатели объявляются с помощью символа «разыменования»
*
:int *p;либо
int* p;Это объявление устанавливает в переменную p указатель на адрес начала целого числа в памяти (4 байта).
Оператор
&
возвращает адрес хранения переменной. В коде ниже p будет указывать на адрес хранения целого числа i
:int i = 5;Если при этом задать
int *p;
p = &i;
*p = 10;Это изменит и значение
i
на 10
.Указатели могут быть объявлены для структур, как в следующем примере:
Coords x = new Coords();Затем можно использовать объявленный указатель
Coords *y = &x;
y
для доступа к открытому полю структуры x
(например, z
):(*y).zлибо через
->
:y -> zНебезопасный Код
Основная проблема с использованием указателей в C# в том, что CLR управляет процессом сбора мусора в фоновом режиме. Освобождая память, сборка мусора может изменить расположение объекта без предупреждения и испортить указатель на него. Это может как поставить под угрозу работу программы, так и повлиять на целостность других программ. Из-за этих проблем использование указателей ограничено кодом, который программист явно помечает как «небезопасный» (
unsafe
).Чтобы решить эту проблему, можно объявить указатель в выражении
fixed
. Это «фиксирует» расположение объекта по указателю, поэтому сборка мусора не ломает указатель. Оператор fixed
может использоваться только в контексте небезопасного кода. При этом типы значений, объявленные в небезопасном коде, автоматически фиксируются, их не нужно использовать в выражениях fixed
.Указатель может быть объявлен для массива:
int[] a = {4, 5};В этом случае
int *b = a;
b
указывает на ячейку памяти с первым элементом массива a
. Элементы также должны быть типа значения. Ниже показано, что можно проходить по значениям массива с помощью указателя:public static void Main() {Источник: https://codewithshadman.com/csharp-pointer/
int[] a = {4, 5};
changeVal(a);
Console.WriteLine(a[0]);
Console.WriteLine(a[1]);
}
public unsafe static void changeVal(int[] a) {
fixed (int *b = a) {
*b = 5;
*(b + 1) = 7;
}
}
День пятьсот одиннадцатый. #CSharp9
C# 9: Упрощённая Проверка Параметров на Null
Эта функция конкурировала с несколькими другими предложениями: атрибуты, флаги компилятора и т.п. Все они были отброшены в пользу узкоспециализированного предложения, которое уменьшает объем кода проверки параметра на
Оператор
1. Проверки на
2. Выполняется именно проверка на равенство
3. В конструкторе проверка произойдет после вызова конструктора базового класса. В Microsoft рассматривали возможность проверки параметров перед вызовом конструктора базового класса. Это всегда было разрешено в .NET и, возможно, это предпочтительнее. Тем не менее, синтаксис C# не позволяет этого, и было решено не генерировать код, который не может быть воссоздан без использования этой функции.
4. В итераторе проверка всегда выполняется при первоначальном вызове.
5. Ошибки компиляции возникнут в случаях:
- проверки параметра, который не может быть
- проверки параметра метода без реализации (например, абстрактного или частичного метода, делегата, метода интерфейса),
- проверки
6. Предупреждения компилятора возникнут в случаях:
- Проверки явно обнуляемого параметра
- Проверки необязательного параметра со значением
Предполагаются следующие сценарии для дженериков:
C# 9: Упрощённая Проверка Параметров на Null
Эта функция конкурировала с несколькими другими предложениями: атрибуты, флаги компилятора и т.п. Все они были отброшены в пользу узкоспециализированного предложения, которое уменьшает объем кода проверки параметра на
null
до одного символа.Оператор
!
может быть расположен после любого идентификатора в списке параметров, что заставит компилятор C# выдать стандартный код проверки на null для этого параметра:void M(string name!) {…}будет скомпилировано как:
void M(string name) {Правила довольно очевидны:
if (name is null)
throw new ArgumentNullException(nameof(name));
…
}
1. Проверки на
null
вводятся в начале функции перед любым другим кодом и выполняются в том же порядке, что и параметры в сигнатуре функции.2. Выполняется именно проверка на равенство
null
, игнорируя любые перегрузки оператора ==
.3. В конструкторе проверка произойдет после вызова конструктора базового класса. В Microsoft рассматривали возможность проверки параметров перед вызовом конструктора базового класса. Это всегда было разрешено в .NET и, возможно, это предпочтительнее. Тем не менее, синтаксис C# не позволяет этого, и было решено не генерировать код, который не может быть воссоздан без использования этой функции.
4. В итераторе проверка всегда выполняется при первоначальном вызове.
5. Ошибки компиляции возникнут в случаях:
- проверки параметра, который не может быть
null
(например, struct
, unmanaged
),- проверки параметра метода без реализации (например, абстрактного или частичного метода, делегата, метода интерфейса),
- проверки
out
параметра.6. Предупреждения компилятора возникнут в случаях:
- Проверки явно обнуляемого параметра
(string? x!)
. Предположительно это не приводит к ошибке, чтобы позволить подклассу быть более строгим, чем базовый класс.- Проверки необязательного параметра со значением
null
по умолчанию.Предполагаются следующие сценарии для дженериков:
void M<T>(T value!) { } // OKНедостаток этого подхода в том, что он не поддерживает проверку свойств, поскольку параметр
void M<T>(T value!) where T : struct { } // ошибка
void M<T>(T value!) where T : unmanaged { } // ошибка
void M<T>(T value!) where T : notnull { } // OK
void M<T>(T value!) where T : class { } // OK
void M<T>(T value!) where T : SomeStruct { } // ошибка
void M<T>(T value!) where T : SomeClass { } // OK
value
не задаётся явно, а только подразумевается. Пользователи предложили обходной путь, в котором оператор !
применяется к ключевому слову set
:public Foo Foo {get; set!;}Источник: https://www.infoq.com/news/2020/06/CSharp-9-Null/
public Bar Bar {
get { return bar; }
set! { bar = value; DoSomethingElse(); }
}
День пятьсот двенадцатый. #Оффтоп
5 Качеств Хорошего Программиста
Сегодня предложу вашему вниманию видео отклассового врага (шутка) джависта и блогера Сергея Немчинского «5 качеств хорошего программиста». Он избрал несколько необычный подход: качества, которые определяют хорошего программиста с точки зрения бизнеса, как хорошего работника, творца, «решателя проблем». Если спросить любого из вас, то вряд ли вы попадёте хотя бы в 2 качества, указанные в видео. Итак:
1. Интеллект
2. Страсть
3. Настойчивость
4. Любовь к новому и самообучению
5. Гибкость мышления
По-моему, интересная точка зрения. Строго говоря, многие из пунктов пересекаются между собой или связаны, а то и противоречат друг другу. Впрочем, не буду пересказывать, в видео Сергей объясняет каждое из качеств более подробно.
Что скажете? Обсудим в чате?
5 Качеств Хорошего Программиста
Сегодня предложу вашему вниманию видео от
1. Интеллект
2. Страсть
3. Настойчивость
4. Любовь к новому и самообучению
5. Гибкость мышления
По-моему, интересная точка зрения. Строго говоря, многие из пунктов пересекаются между собой или связаны, а то и противоречат друг другу. Впрочем, не буду пересказывать, в видео Сергей объясняет каждое из качеств более подробно.
Что скажете? Обсудим в чате?
YouTube
5 качеств хорошего программиста
Сегодня разберём какие пять качеств, я считаю, относятся к хорошему программисту.
Курсы для новичков:
JAVA - https://bit.ly/2Yo6yhm
JAVA Start - https://bit.ly/2zRjTFo
Инструментарий JAVA - https://bit.ly/2NiF2eG
Automation QA (Java) - https://bit.ly/313brhC…
Курсы для новичков:
JAVA - https://bit.ly/2Yo6yhm
JAVA Start - https://bit.ly/2zRjTFo
Инструментарий JAVA - https://bit.ly/2NiF2eG
Automation QA (Java) - https://bit.ly/313brhC…
День пятьсот тринадцатый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
47. Планируйте Свой Следующий Коммит
Я подошёл к трем программистам и спросил, что они делают. «Я делаю рефакторинг этих методов», - ответил первый. «Я добавляю параметры к этому методу действия», - сказал второй. Третий ответил: «Я работаю над этой проблемой пользователя».
Может показаться, что первые двое были поглощены деталями своей работы, тогда как только третий мог видеть более общую картину, и понимал, что он делает. Однако, когда я спросил, когда они закончат и какие изменения сохранят в репозитории, картина резко изменилась. Первые двое достаточно чётко ответили, какие файлы будут задействованы, и что они закончат примерно через час. Третий ответил: «Ну, думаю, что я закончу через пару дней. Скорее всего, я добавлю несколько классов и как-нибудь изменю эти сервисы».
Первые двое не потеряли видения общей картины. Они выбрали задачи, которые, по их мнению, вели их в правильном направлении и могли быть выполнены в течение нескольких часов. После завершения этих задач они бы выбрали новую функцию или рефакторинг для работы над ними. Таким образом, весь процесс написания кода представлял собой цепочку задач с чёткой целью, достижимой в ограниченное время.
Третий программист не смог разобрать проблему на части и работал над всеми аспектами одновременно. Он понятия не имел, что для этого потребуется, в основном занимаясь «предположительным программированием», то есть надеясь в какой-то неопределённый момент в будущем получить что-то работающее, подходящее для коммита. Скорее всего, код, написанный в начале этого длинного сеанса, будет плохо согласован с решением, которое появилось в конце.
Что бы сделали первые два программиста, если бы их задачи заняли более двух часов? Понимая, что они взяли на себя слишком много, они, скорее всего, отбросили бы свои изменения, определили более мелкие задачи и начали сначала. Для продолжения работы не хватало бы сфокусированности, что привело бы к «предположительному программированию» и сохранению в репозитории несогласованного кода. Вместо этого лучше пожертвовать текущими изменениями, но сохранить понимание процесса.
Третий программист может продолжать гадать и отчаянно пытаться собрать все свои изменения во что-то, что может быть сохранено. В конце концов, жалко же выбрасывать кучу изменений, которые уже сделаны, и начинать сначала, не так ли? К сожалению, такая практика приводит к сохранению в репозитории непродуманного кода, которому не хватает чёткой цели.
Иногда даже программисты, сосредоточенные на фиксации сделанных изменений, могут не находить полезного решения, которое по их прикидкам может быть завершено за пару часов. В таком случае можно на время перейти в режим предположений, поиграть с кодом, при этом выбрасывая изменения всякий раз, когда какая-то новая идея возвращает вас в нужное русло. Даже у таких, казалось бы, непродуктивных сессий есть цель: лучше узнать код, чтобы найти способ решить задачу продуктивно.
Планируйте свой следующий коммит. Если вы не можете закончить задачу в разумные сроки, отбросьте свои изменения, а затем определите новую задачу, в завершении которой вы уверены. Проводите эксперименты с «предположительным программированием», когда это необходимо, но не позволяйте себе переходить в режим предположений, не осознавая этого. Не сохраняйте в репозитории «предположительно правильный код».
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Dan Bergh Johnsson
97 Вещей, Которые Должен Знать Каждый Программист
47. Планируйте Свой Следующий Коммит
Я подошёл к трем программистам и спросил, что они делают. «Я делаю рефакторинг этих методов», - ответил первый. «Я добавляю параметры к этому методу действия», - сказал второй. Третий ответил: «Я работаю над этой проблемой пользователя».
Может показаться, что первые двое были поглощены деталями своей работы, тогда как только третий мог видеть более общую картину, и понимал, что он делает. Однако, когда я спросил, когда они закончат и какие изменения сохранят в репозитории, картина резко изменилась. Первые двое достаточно чётко ответили, какие файлы будут задействованы, и что они закончат примерно через час. Третий ответил: «Ну, думаю, что я закончу через пару дней. Скорее всего, я добавлю несколько классов и как-нибудь изменю эти сервисы».
Первые двое не потеряли видения общей картины. Они выбрали задачи, которые, по их мнению, вели их в правильном направлении и могли быть выполнены в течение нескольких часов. После завершения этих задач они бы выбрали новую функцию или рефакторинг для работы над ними. Таким образом, весь процесс написания кода представлял собой цепочку задач с чёткой целью, достижимой в ограниченное время.
Третий программист не смог разобрать проблему на части и работал над всеми аспектами одновременно. Он понятия не имел, что для этого потребуется, в основном занимаясь «предположительным программированием», то есть надеясь в какой-то неопределённый момент в будущем получить что-то работающее, подходящее для коммита. Скорее всего, код, написанный в начале этого длинного сеанса, будет плохо согласован с решением, которое появилось в конце.
Что бы сделали первые два программиста, если бы их задачи заняли более двух часов? Понимая, что они взяли на себя слишком много, они, скорее всего, отбросили бы свои изменения, определили более мелкие задачи и начали сначала. Для продолжения работы не хватало бы сфокусированности, что привело бы к «предположительному программированию» и сохранению в репозитории несогласованного кода. Вместо этого лучше пожертвовать текущими изменениями, но сохранить понимание процесса.
Третий программист может продолжать гадать и отчаянно пытаться собрать все свои изменения во что-то, что может быть сохранено. В конце концов, жалко же выбрасывать кучу изменений, которые уже сделаны, и начинать сначала, не так ли? К сожалению, такая практика приводит к сохранению в репозитории непродуманного кода, которому не хватает чёткой цели.
Иногда даже программисты, сосредоточенные на фиксации сделанных изменений, могут не находить полезного решения, которое по их прикидкам может быть завершено за пару часов. В таком случае можно на время перейти в режим предположений, поиграть с кодом, при этом выбрасывая изменения всякий раз, когда какая-то новая идея возвращает вас в нужное русло. Даже у таких, казалось бы, непродуктивных сессий есть цель: лучше узнать код, чтобы найти способ решить задачу продуктивно.
Планируйте свой следующий коммит. Если вы не можете закончить задачу в разумные сроки, отбросьте свои изменения, а затем определите новую задачу, в завершении которой вы уверены. Проводите эксперименты с «предположительным программированием», когда это необходимо, но не позволяйте себе переходить в режим предположений, не осознавая этого. Не сохраняйте в репозитории «предположительно правильный код».
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Dan Bergh Johnsson
День пятьсот четырнадцатый. #ЗаметкиНаПолях
.NET Core или .NET Framework для Серверных Приложений
На данный момент существуют две реализации .NET для серверных приложений: .NET Framework и .NET Core. Они используют одни и те же компоненты, между ними возможен обмен частями кода. Однако есть и фундаментальные различия.
Использование .NET Core
1. Для создания новых кроссплатформенных приложений.
.NET Core поддерживается в Windows, Linux и macOS как для работы приложений, так и на стадии разработки. Visual Studio предоставляется для Windows и macOS.
2. В микросервисной архитектуре.
Архитектура микросервисов позволяет сочетать различные технологии через сервисы. Например, можно смешивать сервисы, разработанные на .NET Framework, Java, Ruby и других технологиях.
3. При использовании Docker-контейнеров.
Контейнеры обычно используются в сочетании с архитектурой микросервисов. Также их можно использовать в качестве окружающей среды для работы веб-приложений или сервисов, соответствующих любому архитектурному шаблону. .NET Framework можно использовать в контейнерах Windows, а модульность и легковесность .NET Core делают его лучшим выбором при использовании контейнеров. Поскольку он кроссплатформенный, возможно, например, развёртывать серверные приложения в контейнерах Linux.
4. В высокопроизводительных и масштабируемых системах.
Когда системе требуется наилучшая производительность и масштабируемость, лучше всего подойдут .NET Core и ASP.NET Core. Производительность и масштабируемость особенно актуальны для архитектур микросервисов. В ASP.NET Core системы работают с гораздо меньшим количеством серверов/виртуальных машин, что экономит затраты на инфраструктуру и хостинг.
5. Если в приложениях используются различные версии .NET.
.NET Core поддерживает параллельную установку различных версий среды выполнения на одном компьютере. Это позволяет использовать несколько служб на одном сервере, каждая из которых имеет свою собственную версию .NET Core, а также снижает риски и экономит деньги.
Использование .NET Framework
.NET Core предлагает значительные преимущества для новых приложений, однако .NET Framework продолжает оставаться естественным выбором для многих существующих сценариев. В большинстве случаев не нужно переносить существующие приложения в .NET Core. Вместо этого рекомендуется использовать .NET Core при расширении существующего приложения, например создать новый веб-сервис в ASP.NET Core.
Сторонние библиотеки быстро переходят на .NET Standard, обеспечивающий совместное использование кода во всех реализациях .NET, включая .NET Core. С .NET Standard 2.0 это еще проще:
- API существенно расширен.
- Введён режим совместимости с .NET Framework, который позволяет проектам .NET Standard и .NET Core ссылаться на библиотеки .NET Framework.
.NET Framework стоит использовать только в тех случаях, когда библиотеки или пакеты NuGet используют технологии, которых нет в .NET Standard или .NET Core. Кроме того, некоторые технологии .NET Framework недоступны в .NET Core:
- ASP.NET Web Forms
- ASP.NET Web Pages
- Сервисы WCF.
- Службы Workflow и службы данных WCF.
Источник: https://docs.microsoft.com/en-us/dotnet/standard/choosing-core-framework-server
.NET Core или .NET Framework для Серверных Приложений
На данный момент существуют две реализации .NET для серверных приложений: .NET Framework и .NET Core. Они используют одни и те же компоненты, между ними возможен обмен частями кода. Однако есть и фундаментальные различия.
Использование .NET Core
1. Для создания новых кроссплатформенных приложений.
.NET Core поддерживается в Windows, Linux и macOS как для работы приложений, так и на стадии разработки. Visual Studio предоставляется для Windows и macOS.
2. В микросервисной архитектуре.
Архитектура микросервисов позволяет сочетать различные технологии через сервисы. Например, можно смешивать сервисы, разработанные на .NET Framework, Java, Ruby и других технологиях.
3. При использовании Docker-контейнеров.
Контейнеры обычно используются в сочетании с архитектурой микросервисов. Также их можно использовать в качестве окружающей среды для работы веб-приложений или сервисов, соответствующих любому архитектурному шаблону. .NET Framework можно использовать в контейнерах Windows, а модульность и легковесность .NET Core делают его лучшим выбором при использовании контейнеров. Поскольку он кроссплатформенный, возможно, например, развёртывать серверные приложения в контейнерах Linux.
4. В высокопроизводительных и масштабируемых системах.
Когда системе требуется наилучшая производительность и масштабируемость, лучше всего подойдут .NET Core и ASP.NET Core. Производительность и масштабируемость особенно актуальны для архитектур микросервисов. В ASP.NET Core системы работают с гораздо меньшим количеством серверов/виртуальных машин, что экономит затраты на инфраструктуру и хостинг.
5. Если в приложениях используются различные версии .NET.
.NET Core поддерживает параллельную установку различных версий среды выполнения на одном компьютере. Это позволяет использовать несколько служб на одном сервере, каждая из которых имеет свою собственную версию .NET Core, а также снижает риски и экономит деньги.
Использование .NET Framework
.NET Core предлагает значительные преимущества для новых приложений, однако .NET Framework продолжает оставаться естественным выбором для многих существующих сценариев. В большинстве случаев не нужно переносить существующие приложения в .NET Core. Вместо этого рекомендуется использовать .NET Core при расширении существующего приложения, например создать новый веб-сервис в ASP.NET Core.
Сторонние библиотеки быстро переходят на .NET Standard, обеспечивающий совместное использование кода во всех реализациях .NET, включая .NET Core. С .NET Standard 2.0 это еще проще:
- API существенно расширен.
- Введён режим совместимости с .NET Framework, который позволяет проектам .NET Standard и .NET Core ссылаться на библиотеки .NET Framework.
.NET Framework стоит использовать только в тех случаях, когда библиотеки или пакеты NuGet используют технологии, которых нет в .NET Standard или .NET Core. Кроме того, некоторые технологии .NET Framework недоступны в .NET Core:
- ASP.NET Web Forms
- ASP.NET Web Pages
- Сервисы WCF.
- Службы Workflow и службы данных WCF.
Источник: https://docs.microsoft.com/en-us/dotnet/standard/choosing-core-framework-server
День пятьсот шестнадцатый. #Оффтоп
Старший программный менеджер Майкрософт, Мэдс Кристенсен, выпустил подборку расширений для Visual Studio, назвав её Basic Essentials.
Пакет расширений - это одно расширение, которое установит в Visual Studio одно или несколько других расширений. Пакет расширений очень легко сделать (вот руководство). Примеры пакетов расширений: Web Essentials и Extensibility Essentials. Эти два пакета предназначены для очень специфических типов разработки и не подходят ни для каких других.
Пакет от Мэдса полезен для всех разработчиков. Это самые базовые вещи, облегчающие вашу жизнь:
1. Add New File
Расширение для простого добавления новых файлов в любой проект. Просто нажмите
2. Editor Enhancements
Предоставляет дополнительные функции, такие как HTML и URL-кодирование, преобразования и сортировка выделенного текста.
3. EditorConfig Language Service
Помогает разработчикам определять и поддерживать согласованные стили кодирования между различными редакторами и IDE.
4. File Icons
Добавляет значки для файлов, которые не распознаются обозревателем решений.
5. Insert GUID
Вставляет новый GUID, через меню «Правка» или по нажатию
6. Learn the Shortcut
Показывает, как выполнить то же действие, используя только клавиатуру. Отображает в окне Output сочетание клавиш для любой команды, которую вы выполняете, чтобы помочь вам узнать, какие сочетания клавиш вам нужны больше всего.
7. Markdown Editor
Полнофункциональный редактор разметки по типу GitHub с предварительным просмотром в реальном времени и подсветкой синтаксиса.
Исходный код Basic Essentials доступен тут. Это просто файл JSON, созданный определённым образом.
Источник: https://devblogs.microsoft.com/visualstudio/delivering-on-a-promise-the-essential-extension-pack/
Старший программный менеджер Майкрософт, Мэдс Кристенсен, выпустил подборку расширений для Visual Studio, назвав её Basic Essentials.
Пакет расширений - это одно расширение, которое установит в Visual Studio одно или несколько других расширений. Пакет расширений очень легко сделать (вот руководство). Примеры пакетов расширений: Web Essentials и Extensibility Essentials. Эти два пакета предназначены для очень специфических типов разработки и не подходят ни для каких других.
Пакет от Мэдса полезен для всех разработчиков. Это самые базовые вещи, облегчающие вашу жизнь:
1. Add New File
Расширение для простого добавления новых файлов в любой проект. Просто нажмите
Shift+F2
, чтобы создать пустой файл в выбранной папке или в той же папке, что и выбранный файл.2. Editor Enhancements
Предоставляет дополнительные функции, такие как HTML и URL-кодирование, преобразования и сортировка выделенного текста.
3. EditorConfig Language Service
Помогает разработчикам определять и поддерживать согласованные стили кодирования между различными редакторами и IDE.
4. File Icons
Добавляет значки для файлов, которые не распознаются обозревателем решений.
5. Insert GUID
Вставляет новый GUID, через меню «Правка» или по нажатию
CTRL+K,Пробел
.6. Learn the Shortcut
Показывает, как выполнить то же действие, используя только клавиатуру. Отображает в окне Output сочетание клавиш для любой команды, которую вы выполняете, чтобы помочь вам узнать, какие сочетания клавиш вам нужны больше всего.
7. Markdown Editor
Полнофункциональный редактор разметки по типу GitHub с предварительным просмотром в реальном времени и подсветкой синтаксиса.
Исходный код Basic Essentials доступен тут. Это просто файл JSON, созданный определённым образом.
Источник: https://devblogs.microsoft.com/visualstudio/delivering-on-a-promise-the-essential-extension-pack/
День пятьсот семнадцатый. #Оффтоп
Сегодня расскажу про ещё один плейлист на ютуб. На канале Microsoft Visual Studio в серии Visual Studio Toolbox вышел довольно хороший и актуальный обзор Entity Framework Core.
Почему-то авторы решили не выделять эту серию в отдельный плейлист, поэтому я сделал это сам: Плейлист по Entity Framework Core.
Эпизоды серии делятся на 2 части.
Основные понятия:
1. Работа с существующей БД.
2. Отслеживание изменений.
3. Основные запросы.
4. Запросы связанных данных и использование проекций.
5. Обзор CUD (создание/обновление/удаление) в CRUD.
Код примеров из этой части доступен на GitHub.
Расширенное использование:
1. Производительность.
2. Модели представления.
3. Настройки.
4. Построение модели.
5. Глобальные фильтры запросов.
6. Конфликты изменений.
7. Устойчивость подключения.
8. Вычисляемые столбцы.
9. Управление событиями отслеживания.
10. Маппинг полей.
В этой части вышли ещё не все видео, буду добавлять их в плейлист по мере выхода.
Код примеров из этой части также доступен на GitHub.
Сегодня расскажу про ещё один плейлист на ютуб. На канале Microsoft Visual Studio в серии Visual Studio Toolbox вышел довольно хороший и актуальный обзор Entity Framework Core.
Почему-то авторы решили не выделять эту серию в отдельный плейлист, поэтому я сделал это сам: Плейлист по Entity Framework Core.
Эпизоды серии делятся на 2 части.
Основные понятия:
1. Работа с существующей БД.
2. Отслеживание изменений.
3. Основные запросы.
4. Запросы связанных данных и использование проекций.
5. Обзор CUD (создание/обновление/удаление) в CRUD.
Код примеров из этой части доступен на GitHub.
Расширенное использование:
1. Производительность.
2. Модели представления.
3. Настройки.
4. Построение модели.
5. Глобальные фильтры запросов.
6. Конфликты изменений.
7. Устойчивость подключения.
8. Вычисляемые столбцы.
9. Управление событиями отслеживания.
10. Маппинг полей.
В этой части вышли ещё не все видео, буду добавлять их в плейлист по мере выхода.
Код примеров из этой части также доступен на GitHub.