.NET Разработчик
6.56K subscribers
443 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День семьсот девяносто третий.
Как Просканировать NuGet Пакеты на Наличие Уязвимостей
Открытый исходный код есть везде. Для организаций и частных лиц вопрос сегодня не в том, используете ли вы открытый код или нет, а в том, какой открытый код вы используете и в каком объёме.

Если вы не знаете, что находится в вашей системе, уязвимость, появившаяся в одной из ваших зависимостей, может стать фатальной и сделать вас и ваших клиентов уязвимыми для потенциального взлома.

Сегодня в NuGet доступны функции для защиты от уязвимостей, которые вы можете использовать, чтобы гарантировать, что ваши проекты свободны от уязвимостей, либо принять меры по защите вашего ПО.

Что такое CVE/GHSA?
NuGet получает информацию об уязвимостях непосредственно из централизованной базы данных GitHub Advisory. База данных предоставляет два основных списка уязвимостей:
1. CVE (Common Vulnerabilities and Exposures) - список публично раскрытых общих уязвимостей и недостатков.
2. GHSA (GitHub Security Advisory) - это рекомендации по безопасности от GitHub. Подробности можно почитать тут.

Описания пакетов на NuGet.org
Вы можете видеть любые известные уязвимости прямо на NuGet.org. NuGet.org покажет баннер, сообщающий об обнаружении уязвимости с определенной степенью серьёзности и действиях, которые вы можете предпринять, чтобы защитить себя.

Авторы пакетов увидят баннер, сообщающий о том, что в конкретной версии пакета обнаружена уязвимость, а также рекомендации по её устранению.

Кроме того, в списке пакетов вы увидите предупреждающий значок, означающий, что была обнаружена уязвимость.

dotnet CLI
Вы можете вывести список всех известных уязвимостей в зависимостях ваших проектов и решений с помощью команды
dotnet list package --vulnerable

Команда выдаст список уязвимостей в пакетах верхнего уровня, версию пакета, в которой она исправлена и ссылку на рекомендации. Если вы хотите увидеть уязвимости в дочерних пакетах, используйте параметр --include-transitive.

Чтобы найти уязвимости в своих проектах, загрузите .NET SDK 5.0.200, Visual Studio 2019 16.9 или Visual Studio 2019 для Mac 8.8, который включает .NET SDK.

Источник: https://devblogs.microsoft.com/nuget/how-to-scan-nuget-packages-for-security-vulnerabilities/
День семьсот девяносто четвёртый. #ЧтоНовенького #CSharp10
3 Потенциальных Новинки в C# 10
10я версия языка не за горами, пора потихоньку знакомиться с тем, что нас ждёт. Сразу дисклеймер: следующие функции пока только в списке на включение в новую версию языка, но не факт, что они появятся и именно в описанном виде.

1. Пространства имён на уровне файла
Пространства имён – удобная вещь для логического разделения ваших классов. Единственный их недостаток – лишний уровень отступов и лишние фигурные скобки вокруг их содержимого. Предлагается объявлять пространство имён в начале файла, чтобы оно действовало на весь файл.
namespace HelloWorld;
public class Hello {

}
Можно иметь только одно пространство имён уровня файла, однако ничего не мешает вам создать вложенное пространство имён, заключив его код, как обычно, в фигурные скобки.

Небольшое изменение, но иногда от таких мелких улучшений больше всего пользы.

2. Обобщённые атрибуты
Этому предложению уже несколько лет, но, похоже, сейчас за него решили-таки взяться. И действительно, IL позволяет их использовать, почему бы не добавить эту функциональность в C#. Например, вместо:
[TypeConverter(typeof(X))]
использовать
[TypeConverter<X>]

3. «Необработанные» строки
Обычно использовать строковые литералы в коде, особенно длинные, - довольно муторное занятие. Нужно экранировать все кавычки, слеши и переводы строки. дословные (verbatim) строки серьёзно упростили жизнь при использовании URL или регулярных выражений, но всё равно приходится экранировать кавычки, которые в некоторых случаях, например, в коде XML или JSON, используются довольно часто.

Необработанные (raw) строки предлагают вам использовать строковые литералы «как есть». Они используют новый маркер начала и конца строки – несколько кавычек и новая строка в начале, новая строка и столько же кавычек в конце. Между ними просто вставляйте блок текста, который будет трактоваться как одна строка. Проще показать на примере:
string xml = """
<part number="1976">
<name>Windscreen Wiper</name>
<description>The "Windscreen wiper" automatically removes rain from your windscreen. It has a rubber <ref part="1977">blade</ref>, which can be ordered separately.</description>
</part>
""";
Если вам нужно использовать в тексте тройные кавычки, можете обозначить начало и конец строки четырьмя кавычками и т.д.

Так же, как и с дословными строками, все пробелы и разбиение на строки сохраняются. Необработанные строки не призваны заместить собой дословные строки. Они просто будут ещё одним вариантом использования, когда вам нужно вставить блок кода в строку, как есть, и не переживать по поводу форматирования его.

Источник: https://medium.com/young-coder/c-10-3-candidate-features-that-could-make-the-final-cut-3b46f4a62284
День семьсот девяносто пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
83. Тестирование – Это Строгость в Разработке Программного Обеспечения
И снова о тестировании.

Разработчики обожают использовать сложные метафоры, пытаясь объяснить, что они делают, членам семьи, супругам и просто гуманитариям. Мы часто используем в качестве примера строительство мостов и другие реальные инженерные конструкции. Однако все эти метафоры быстро рушатся, если вы заходите слишком далеко в объяснения. Оказывается, разработка программного обеспечения не похожа на разработку реальных объектов во многих важных аспектах.

Разработку ПО можно было бы сравнить со сложной инженерией, только если бы стратегия строительства моста заключалась в том, чтобы построить мост, а затем пустить по нему тяжёлую технику. Если мост выдержит, это хороший мост. Если нет, то… возвращаемся к чертежам. За последние несколько тысяч лет инженеры далеко продвинулись в математике и физике, которые они могут использовать для создания рабочего решения, без необходимости строить что-то вслепую и проверять это на практике. В программировании нет ничего подобного и, возможно, никогда не будет, потому что программирование на самом деле сильно отличается от создания чего-то материального.

Тестировать материальные вещи сложно, потому что нужно физически построить то, что вы хотите протестировать. Не очень заманчиво строить что-то только для того, чтобы посмотреть, что произойдет. Но процесс создания программного обеспечения обходится значительно дешевле. Мы разработали целую экосистему инструментов, которые упрощают это: модульное тестирование, mock-объекты, платформы для тестирования и многое другое. Инженеры из других областей могут только мечтать иметь возможность что-то построить и протестировать в реальных условиях. Как разработчики ПО, мы должны рассматривать тестирование как основной (но не единственный) механизм проверки программного обеспечения. Вместо того, чтобы производить какие-то предварительные расчёты поведения программы, в нашем распоряжении уже есть инструменты для реализации лучших практик разработки. То есть у нас есть противоядие против менеджеров, которые говорят: «У нас нет времени на тестирование». Строитель моста никогда не услышит от своего начальника: «Не беспокойтесь о проведении структурного анализа этого объекта - у нас очень сжатые сроки». Признание того, что тестирование - это действительно путь к воспроизводимости и качеству программного обеспечения, позволяет нам, разработчикам, отвергать аргументы против тестирования, как непрофессиональные и безответственные.

Тестирование требует времени, как и структурный анализ. Оба вида деятельности обеспечивают качество конечного продукта. Разработчикам программного обеспечения пора взять на себя ответственность за то, что они производят. Одного тестирования недостаточно, но оно необходимо.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Neal Ford
День семьсот девяносто шестой. #ЗаметкиНаПолях #SQL
Ограничение Результатов с Помощью Оконных Функций
Оконные (window) аналитические функции давно присутствуют в SQL, однако многие до сих пор не умеют их применять.

Окно (window) - это набор строк таблицы, которые можно анализировать или применить к ним функцию. Строки должны быть как-то связаны. Иногда они связаны с конкретной строкой, т.е. строки могут быть выше или ниже друг друга или в пределах заданного диапазона. Либо связь может быть основана на отдельных группах данных в наборе.

Все оконные функции следуют определенному синтаксису.
<название функции>(<выражение>) OVER (
<окно>
<сортировка>
)

Сначала идёт название функции, а за ним следует предложение OVER. Оно определяет область действия окна, указывая набор строк, к которым будет применяться функция. Предложение OVER является обязательной частью оконной функции. Остальной синтаксис является необязательным, и зависит от желаемой области действия:
- Выражение PARTITION BY можно использовать для разделения набора данных на отдельные группы (аналогично GROUP BY).
- Выражение ORDER BY используется для упорядочивания строк в каждой группе.

В качестве оконных можно использовать простые агрегатные функции, вроде SUM(), COUNT(), AVG() и т.п. Но есть и несколько специальных.

Номера и ранг строк
Простейший вариант применения оконной функции – вывести номера строк результата (см. пример 1 на картинке ниже). Здесь «окном» является весь набор, а функция ROW_NUMBER() выводит номер строки по порядку.
Мы можем разделить набор данных на группы, используя PARTITION BY. В примере 2 на картинке ниже тот же набор разделён по полю name, а внутри каждой такой группы упорядочен по полю course.

Кроме этого две функции RANK() и DENSE_RANK() выводят ранг строки. Они отличаются от ROW_NUMBER() тем, что при равенстве результатов задают строкам одинаковые значения. При этом DENSE_RANK() продолжает нумерацию, например, 1,1,2,2,3. А RANK() использует следующий номер строки по порядку, оставляя разрывы в нумерации: 1,1,3,3,5. В примере 3 на картинке ниже приводится сравнение этих функций на том же наборе данных. Здесь использована сортировка всего набора по полю name, без разбиения на группы.

Заметьте, что выражение ORDER BY внутри оконной функции никак не связано с выражением ORDER BY всего запроса. Оно влияет только на результаты оконной функции. В предыдущем примере мы могли бы добавить ORDER BY ко всему запросу и изменить порядок строк в запросе, но результаты функций ROW_NUMBER(), RANK() и DENSE_RANK() в строках не изменились бы.

Первое и последнее значение
Эти функции позволяют вывести первое или последнее соответственно значение столбца в группе. В отличие от функций, описанных выше, для каждой группы будет выведена только одна строка. Например, если использовать LAST_VALUE(course) на наборе данных из примера 2(последний по алфавиту курс для каждого студента), то будет выведено 3 строки:
Jason Economics
Lucy Health Science
Martha Biology
.

Предыдущие и последующие строки
Часто бывает полезно сравнивать строки с предыдущими или последующими, особенно если данные упорядочены (например, хронологически). Для этого используются функции LAG(), которая извлекает значения из предыдущих строк, и LEAD(), которая извлекает значения из последующих строк. В примере 4 на картинке ниже мы получаем значение суммы из предыдущего месяца с помощью функции LAG(sales,1). В функцию, помимо названия столбца, передаётся целое число, означающее количество строк, которые нужно отсчитать от текущей (в нашем случае 1). Для первой строки, очевидно, нет предыдущего значения, поэтому функция возвращает NULL.

Источник: https://app.pluralsight.com/library/courses/combining-filtering-data-postgresql
День семьсот девяносто седьмой. #Шпаргалка
20 Команд Git, Которые Надо Знать
Git был выпущен в 2005 году. Несмотря на то, что сейчас появилось много программ с графическим интерфейсом для управления репозиторием, труЪ программеры используют консоль. Поэтому ловите 20 наиболее полезных команд Git, которые понадобятся любому разработчику. Подробности о работе Git см. начиная с этого поста.

1. Вывести конфигурацию
git config -l
Эта команда отображает список информации о вашей конфигурации git, включая имя пользователя, адрес электронной почты, редактор кода по умолчанию и т.д.

2. Изменить ваше имя пользователя
git config --global user.name "<ваше имя>"

3. Изменить ваш email
git config --global user.email "test@email.com"

4. Создать репозиторий
git init
Эта команда инициализирует репозиторий в текущей папке.

5. Добавить файл в staging
git add my_file

6. Добавить все файлы в staging
git add .

7. Проверить статус
git status
Эта команда покажет статус текущего репозитория, включая текущую ветку, и файлы как в staging, так и не добавленные туда.

8. Commit
git commit
Эта команда создаст коммит. В этом варианте откроется текстовый редактор, куда вам нужно будет записать сообщение коммита.

9. Commit с сообщением
git commit -m "Ваше сообщение"

10. Просмотр истории
git log

11. Список веток
git branch

12. Создание ветки
git branch my_branch
Заметьте, что Git не переключится на эту ветку автоматом. Для этого см. пункт 14.

13. Удаление ветки
git branch -d my_branch
Обратите внимание на флаг -d.

14. Переключение между ветками
git checkout my_branch

15. Создание ветки и переключение на неё
Пункты 12 и 14 можно объединить в одну команду:
git checkout -b branch_name

16. Добавление удалённого репозитория
git add remote https://repo_url

17. Публикация в удалённый репозиторий
git push

18. Обновление из удалённого репозитория
git pull

19. Временное сохранение изменений
git stash
Эта команда временно сохранит неподтверждённые изменения и вернёт ваш репозиторий в состояние последнего коммита.

20. Получение временно сохранённых изменений
git stash pop
Эта команда применит сохранённые ранее изменения обратно к вашему репозиторию.

Источник: https://www.c-sharpcorner.com/article/20-git-commands-you-should-know/
День семьсот девяносто восьмой. #юмор
Ооо, это про меня.
День семьсот девяносто девятый. #ЗадачиНаСобеседовании
Сегодня предложу вам к просмотру ещё один минисериал от Nick Chapsas на тему заданий на собеседовании. На этот раз Ник разбирает задачу интеграции API сервиса.

Смысл задачи в том, что вам дан REST API (в данном случае API сети ресторанов), вам нужно создать клиента этого API, отвечающего определённым требованиям.

Все подробности задачи Ник объясняет в видео, поэтому не буду их пересказывать.

В первой части https://youtu.be/_Pjjk4fOh8s довольно подробно описывается создание консольного клиента API. Что хотелось бы отметить из решения – это пакеты, которые Ник использует (помимо стандартных):
1. RefitClient – пакет, который создаёт код клиента API на основе интерфейса.
2. CommandLineParser – о нём я уже писал.
3. OneOf – пакет для объединения различных типов в один тип OneOf<T0,T1,…Tn>. Ник использует его для возврата из метода обобщённого объекта с результатом либо ошибкой. Вызывающий код может использовать методы Match() или Switch(), чтобы выполнять действия в зависимости от типа ответа. Не могу сказать, что мне нравится такой подход, но упоминания он заслуживает.
4. Microsoft.Extensions.Http.Polly – Polly на канале уже тоже упоминался, и не раз. Это, насколько я понимаю, версия от Mirosoft, доступная в .NET 5.

Вторая часть https://youtu.be/NPAK94ZCxD4 посвящена тестированию. И помимо обычных модульных тестов Ник описывает приёмочное (acceptance) тестирование: близкое к человеческому языку описание теста, которое парсится в коде и проверяется автоматически. «Ничего не понятно, но очень интересно»))) Кстати, подробно о приёмочном тестировании есть и третье видео https://youtu.be/qWEDkHGNhvk
День восьмисотый.
Как Измерить Время Исполнения Программ в PowerShell
Командная строка используется всё чаще для запуска сценариев, сборки и других задач, вроде docker и docker-compose. Когда вы запускаете команду, например, dotnet build или dotnet test, она обычно сообщает вам о том, сколько времени потребовалось для выполнения. Но когда у вас есть сценарий, состоящий из нескольких шагов, часто хочется проверить, сколько времени он выполняется. Чтобы оптимизировать его или сравнить время на разных машинах.

Вы можете это сделать с помощью команды Measure-Command:
Measure-Command { ./SomeScript.ps1 }

Она запустит скрипт и предоставит отчет о том, сколько времени он занял. Также можно запускать произвольные команды CLI:
Measure-Command { dotnet build }

Но по умолчанию вы не получаете никакого вывода от выполняемой команды. Чтобы видеть его, нужно добавить параметр вывода (см. картинку):
Measure-Command { dotnet build | Out-Default }

Источник: https://ardalis.com/measure-command-line-script-time-elapsed/
День восемьсот первый.
Как Улучшить Свои Навыки Отладки. Начало
Независимо от того новичок вы или опытный разработчик, время от времени в вашем коде появляются ошибки. Все мы иногда делаем ошибки. В конце концов, невозможно перестать быть человеком. Есть три основных способа борьбы с ошибками:
1. Пред-отладка: снижение вероятности возникновения ошибок.
2. Отладка: выявление, исправление и удаление ошибок после их обнаружения.
3. Пост-отладка: анализ исправленных ошибок и отслеживание непредвиденных ошибок.

Что такое пред-отладка?
«Отладка - это процесс выявления и устранения ошибок в ПО.»
Но разве это всё? Хорошие разработчики улучшают свои инструменты и самих себя, чтобы в первую очередь уменьшить количество создаваемых ими ошибок. Вот некоторые способы этого добиться:
1. Планируйте перед написанием кода
Многие новички не совсем понимают программы, над которыми они работают, а некоторые из них даже не пытаются понять сообщения об ошибках, прежде чем искать их в сети. Важно понимать, что должен делать код, хотя бы по следующим пунктам:
- Какие будут входные данные, их структура и особенности.
- Что мы будем делать с ними.
- Что будет в результате.
- Что будет, если входные данные не такие, как мы ожидаем.
Такое планирование не только помогает уменьшить количество ошибок, но и помогает писать эффективные тесты.

2. Изучите основные инструменты, которые вы часто используете
Выберите встроенный метод или функцию языка и спросите себя: «Что она принимает? Что возвращает? Что произойдёт, если будет указан недопустимый аргумент?» Вы уверены в своих ответах? Загляните в документацию, вы можете найти там много нового. Такие регулярные упражнения помогут вам отточить свои навыки и использовать инструменты языка правильно.

3. Учитесь печатать без ошибок
Да, многие редакторы и компиляторы укажут вам на опечатку, но случаи бывают разные. Да и исправление опечаток – просто ненужная трата времени.

4. Подтяните английский
Знание английского сильно поможет, как в работе с инструментами и понимании сообщений об ошибках, так и в поиске ответа в сети. В англоязычном сегменте интернета информации гораздо больше, и она намного актуальнее.

5. Изучите сообщения об ошибках и возможные решения
Сколько раз вы видели в чатах и форумах скрины с элементарными ошибками и вопросом, как это исправить, хотя даже в сообщении об ошибке иногда всё написано? Не надо так делать. Не бегите сразу гуглить возникшую ошибку, а хотя бы попытайтесь понять, что вам говорит компилятор.

6. Не используйте то, чего не понимаете
Один из лучших способов уменьшить количество ошибок - использовать только те подходы, методы и классы, которые вы понимаете. Есть большой соблазн скопировать кусок кода со Stackoverflow, ведь он, судя по описанию, делает то, что вам надо. Остановитесь. Изучите его и убедитесь, что он делает именно то, что описано, и то, что вам нужно.

7. Наблюдайте за отладкой коллег
Это помогает увидеть различные методы отладки. Всегда найдутся инструменты или подходы, о которых вы не знаете или которые не используете. Или даже если вы знаете об них, вы можете не знать, в каких случаях и как их можно применять.

8. Пишите тесты
Об этом я пишу по нескольку раз в неделю. Хотя бы вот, из личного опыта.

Окончание следует…

Источник:
https://www.freecodecamp.org/news/how-to-improve-your-debugging-skills/
День восемьсот второй.
Как Улучшить Свои Навыки Отладки. Окончание
Начало

Что такое отладка?
Отладка лежит в основе программирования, и при кодировании она занимает большую часть вашего времени. Отладка включает три основных этапа:
1. Поиск ошибки
Поиск ошибок начинается с понимания сообщений об ошибках, которые вы видите. Сообщение об ошибке - это указатель на ошибку. Если вы его понимаете, вы можете точно определить местонахождение ошибки.

Но некоторые ошибки могут быть сложными и сообщение можно не указывать прямо на источник ошибки. Чтобы найти ошибку, необходимо:
- Четко выразить, какого результата работы программы вы ожидаете.
- Сравнить свои ожидания и фактический результат.
- Проанализировать, что не так.
Можно использовать отладчик, трассировку и другие инструменты, чтобы проверить различные части вашего кода на соответствие своим предположениям и быстрее найти ошибки.

2. Анализ и понимание причин возникновения ошибки
После обнаружения ошибки нужно выяснить, почему код ведёт себя именно так. Это поможет вам построить более эффективную систему. Вместо этого многие разработчики просто гуглят и используют ответы со StackOverflow. Иногда этого достаточно, но лучше понять причину ошибки и почему найденное решение работает. Понимание причины ошибки - важный шаг на пути к её исправлению.

3. Исправление ошибки
После обнаружения и понимания причины ошибки мы должны исправить её. Иногда, если вы понимаете, в чём ошибка, вы быстро найдёте решение. Однако бывают случаи, когда даже понимание не даёт решения, как бы мы ни старались. Не тратьте слишком много времени на раздумья, поищите подходящее решение в интернете по коду или сообщению об ошибке или другому подходящему запросу. Также можно спросить коллегу, или задать вопрос на форуме, на StackOverflow, в чате, где-угодно (но только после того, как вы самостоятельно обдумали проблему!). Люди склонны видеть вещи по-разному, взгляд на проблему со стороны может помочь. Иногда даже само объяснение проблемы другому человеку помогает найти решение.

Исправление назойливой ошибки - всегда волнительно. Но не слишком увлекайтесь. Исправление одной ошибки может внести другую. Поэтому сначала убедитесь, что вы не добавили в программу ещё одной проблемы. Ещё один плюс наличия автоматизированных тестов.

Что такое пост-отладка?
Пост-отладка - это анализ исправленной ошибки и предупреждение её возникновения в будущем. Задайте себе несколько вопросов:
- Почему возникла эта ошибка? Из-за невнимательности, недостатка знаний или чрезмерной сложности кода.
- Есть ли в других частях системы ошибки того же типа?
- Часто ли у вас возникают ошибки такого типа, и что стоит сделать, чтобы исключить их в будущем? Подтянуть знания по этой теме, упростить код, и т.п.

Кроме того, ошибки непременно будут возникать по мере использования вашей программы. Поэтому вновь возникающие ошибки необходимо отслеживать и обрабатывать.

В этом помогут системы отслеживания ошибок (баг-трекеры), которых сейчас невероятное множество, и использовать их довольно просто.

Источник: https://www.freecodecamp.org/news/how-to-improve-your-debugging-skills/
День восемьсот третий. #ВопросыНаСобеседовании
Попробую новый вид постов на тему вопросов на собеседовании. Подписчик прислал набор вопросов, которые ему недавно задали на собеседовании и попросил оценить. Попробую сам ответить и прокомментировать, а также жду комментариев от вас. Как по поводу ответов, так и по поводу, как вам вопросы и как вообще такой формат.

Поехали!

Дисклеймер: вопросы буду приводить в том виде, как они мне были присланы. Я постараюсь не гуглить правильные ответы, а приведу свои мысли. Поэтому мои ответы не обязательно будут правильными. Если что, поправляйте в комментариях.

Внутренности .NET
1) Есть класс Object. У него определенны Equals и GetHashCode. Если вы переопределите Equals, но не переопределите GetHashCode для какого-нибудь класса, компилятор выдаст вам Warning. Почему?
Методы Equals и GetHashCode связаны в том смысле, что GetHashCode должен выдавать одинаковый результат у объектов, для которых Equals выдаёт true. Поэтому переопределение Equals скорее всего потребует и переопределения GetHashCode.
Подробнее об Equals
Подробнее о GetHashCode

2) В классе Dictionary, когда происходит поиск по ключу. Какая сложность? А в List при вызове FirstOrDefault()?
В Dictionary поиск по ключу происходит со сложностью O(1) из-за хеширования ключей. В List – первый элемент выберется за O(1), но если до этого будет поиск по индексу, то O(n).
Подробнее

3) Есть конструкция async/await. Как она работает? Когда добавляю async и await, что там меняется относительно того, если бы я не добавлял.
Создаётся конечный автомат для сохранения состояния. Все инструкции после строки с await добавляются в функцию продолжения, которая вызывается после завершения ожидания инструкции, следующей за await.
Подробнее

4) У меня была операция File.ReadAll(), я заменил ее на File.ReadAllAsync() какая из этих операций будет быстрее?
Странный вопрос, на мой взгляд, о сферическом быстродействии в вакууме. Тут столько неизвестных, что определённо ответить на этот вопрос просто невозможно. Скорее всего разницы в быстродействии не будет заметно, т.к. время на чтение файла будет на порядок превышать затраты на асинхронность.

5) Если синхронные методы работают быстрее чем асинхронные, зачем нам нужная асинхронная модель?
Опять какое-то теоретизирование о быстродействии синхронных и асинхронных методов. Быстродействие надо измерять в каждом конкретном случае. А вообще асинхронные методы используются для исключения блокировки UI потока, а также для операций, не использующих процессор, вроде чтения/записи файлов, обращения к БД или сетевых вызовов.

6) Есть I/O Bound потоки и CPU Bound потоки. Какая разница между ними?
Эти потоки различаются по типу нагрузки на ресурсы компьютера. I/O Bound поток больше нагружает диск (чтение/запись файлов), CPU Bound поток больше нагружает процессор (вычислительные операции).

7) File.ReadAllAsync() какого типа поток?
Совсем не понял вопроса. Начнём с того, что нет метода ReadAllAsync(), есть ReadAllBytesAsync(), возвращающий Task<byte[]>, и ReadAllTextAsync(), возвращающий Task<string>.

8) Task.Run(t => File.ReadAll()) и File.ReadAllAsync() это эквивалентные вызовы? Объясните.
Отвлечёмся от того, что снова указаны несуществующие методы. Здесь, если выполнить так, как написано, то, насколько я понимаю, Task.Run не возвратит результата.

9) Есть строковая переменная, в ней написано название типа, я хочу создать объект этого типа. Как мне это сделать? Корректировка: Тип ты не знаешь в Compile Time.
Использовать Activator.CreateInstance(). Подробности на память не помню, надо гуглить.

Как вам вопросы? Что скажете о моих ответах? Стоит ли продолжать выпускать такие посты?
👍4
День восемьсот четвёртый. #ЗаметкиНаПолях
Что такое Debugger.Launch?
Допустим, вы запускаете приложение (например, веб-приложение или службу Windows), в котором есть startup метод, который вы хотите отладить. Часто это может быть настройка внедрения зависимостей, раннее чтение файла конфигурации или что-то подобное. Допустим, вы не можете просто нажать F5 в Visual Studio и начать отладку. Вам нужно запустить приложение, а потом подключить отладчик. Для веб-приложений это иногда связано с тем, что вы используете IIS и переходите по URL-адресу своего приложения. А службу Windows, вы хотите отладить, когда она на самом деле исполняется как служба Windows.

Можно добавить в нужное место кода Thread.Sleep(10000); и попытаться подключить отладчик, в течение этого времени. Но гораздо проще это сделать с помощью:
System.Diagnostics.Debugger.Launch();

Тогда, если вы запустите приложение (не через отладку из Visual Studio), то, когда исполнение дойдёт до этой строчки, появится диалоговое окно, где вам будет предложено выбрать отладчик для этого приложения. Можно выбрать Visual Studio, и приложение откроется в режиме отладки.

А что насчёт Debugger.Break()?
Этот метод также использовался для начала отладки. Но, как говорится в документации Microsoft, начиная с .NET Framework 4, если не выбран отладчик, то не гарантируется, что метод Break приведёт к вызову окна выбора отладчика. Вместо этого в систему отчётов об ошибках Windows (WER) направляется сообщение об ошибке. Таким образом, документация советует для старта отладчика использовать Debugger.Launch.

Если же отладчик уже подключен, Debugger.Break заставляет код останавливать выполнение так же, как и точка останова. Так что в некотором смысле это похоже на точку останова, которую могут использовать разработчики на разных машинах вместо ручной инструкции: «Поместите точку останова в строку XX файла YYY…». Это может показаться не очень полезным, кроме случая, который мы рассмотрим далее.

Когда Debugger.Launch не работает
В очень редких случаях Debugger.Launch не предлагает пользователю отладить код. Либо требуется отладка в приложении, не представленном во всплывающем окне. Тогда есть простое решение:
// Ждём подключения отладчика.
while(!System.Diagnostics.Debugger.IsAttached)
{
Thread.Sleep(100); //либо Task.Delay()
}
System.Diagnostics.Debugger.Break();

Если отладчик не подключен, программа ожидает его подключения в бесконечном цикле. После подключения отладчика цикл будет прерван, и мы продолжим выполнение. Debugger.Break немедленно останавливает выполнение и действует как точка останова, позволяя нам начать пошаговое выполнение кода, если мы хотим.
Этот код можно обернуть в конструкцию
#if DEBUG

#endif

Тогда ожидание отладчика будет выполняться только в режиме отладки, и не затронет производственный код.

Источник: https://dotnetcoretutorials.com/2021/04/03/i-wish-i-knew-about-debugger-launch-earlier/
День восемьсот пятый.
Microsoft Azure Virtual Training Day: DevOps with GitHub
Рекомендую посетить очередной бесплатный вебинар из серии Microsoft Azure Virtual Training Day. На нём расскажут, как использовать GitHub для управления рабочими процессами и сокращения цикла разработки. Пошаговые инструкции по добавлению элементов управления качеством и безопасностью в процесс сборки, а также по улучшению уведомлений и ответов для обеспечения согласованной и повторяемой автоматизации.

Темы мероприятия:
- Использование GitHub для улучшения совместной работы и производительности команды.
- Интеграция средств контроля безопасности и качества в конвейеры автоматизации, непрерывной интеграции и непрерывной доставки (CI/CD) и среды выполнения.
- Внедрение передовых методов, чтобы помочь удаленным командам разработчиков повысить отказоустойчивость программного обеспечения.

Вебинар пройдёт в 2 дня:
Среда, 21 апреля 2021, 11:00-13:55 Мск.
Четверг, 22 апреля 2021, 11:00-13:10 Мск.
Язык: Английский, доступны русские субтитры.

Регистрация по ссылке: https://mktoevents.com/microsoft+event/247969/157-gqe-382
День восемьсот шестой. #юмор
Большая техническая конференция о .NET-разработке начинается уже на следующей неделе.

DotNext 2021 — 20-23 апреля, онлайн.

4 дня, несколько десятков докладов и воркшопов от авторов популярных технологий и инструментов, живое общение со спикерами и коллегами и многое другое.

А еще возможность пообщаться со спикерами и коллегами в дискуссионных Zoom-комнатах, возможность вернуться к записям эфира и куча других кайфовых штук.

Посмотреть всю программу и купить билет со скидкой можно на https://bit.ly/3dYUGJk

Промокод на Personal-Standard билет: netdevdiary2021JRGpc
Промокод на Full Pass билет: JugRuCommunityBonus – это если решите посмотреть все конференции сезона 😉
День восемьсот седьмой.
FluentValidation
Сегодня предлагаю вам посмотреть полезное видео - запись вебинара «OSS Power-Ups: FluentValidation». Это первый вебинар из серии Open-Source Power-Ups про популярные проекты с открытым исходным кодом в сообществе .NET.

FluentValidation - это библиотека для создания строго типизированных правил валидации, пользующаяся огромной популярностью и имеющая более 50 миллионов загрузок на NuGet. Джереми Скиннер, поддерживающий проект, поможет нам начать работу с некоторыми базовыми примерами, написанием пользовательских валидаторов, локализацией сообщений об ошибках и интеграцией валидации в ASP.NET Core.
День восемьсот восьмой. #ЗаметкиНаПолях
Как Посмотреть Параметры Конфигурации в
ASP.NET
Существует простой способ раскрыть конфигурацию приложения как конечную точку в вашем приложении ASP.NET Core.

GetDebugView() - это метод расширения IConfigurationRoot, который возвращает строку, описывающую конфигурацию приложения. В этой строке отображаются все ключи конфигурации в вашем приложении, связанное значение и источник значения.

Рассмотрим пример «стандартного» вывода метода GetDebugView():
AllowedHosts=* (JsonConfigurationProvider for 'appsettings.json' (Optional))
applicationName=temp (Microsoft.Extensions.Configuration.ChainedConfigurationProvider)
ASPNETCORE_ENVIRONMENT=Development (EnvironmentVariablesConfigurationProvider)
ASPNETCORE_URLS=https://localhost:5001;http://localhost:5000 (EnvironmentVariablesConfigurationProvider)
Logging:
LogLevel:
Default=Information (JsonConfigurationProvider for 'appsettings.json' (Optional))
MySecretValue=TOPSECRET (JsonConfigurationProvider for 'secrets.json' (Optional))


Некоторые особенности вывода:
1. Параметры конфигурации выдаются в алфавитном порядке ключей.
2. Формат строки:
Ключ=значение (источник значения)
Например:
- Ключ AllowedHosts имеет значение * и предоставлен из файла appsettings.json провайдером JsonConfigurationProvider.
- Ключ MySecretValue имеет значение TOPSECRET и предоставлен из файла пользовательских секретов secrets.json.
3. Строка отформатирована по разделам, что видно по ключу Logging, содержащему раздел LogLevel, в котором находится ключ Default.
4. Прочие провайдеры конфигурации:
- ChainedConfigurationProvider – первоначальные значения конфигурации, задаются хостом,
- EnvironmentVariablesConfigurationProvider – переменные среды,
- CommandLineConfigurationProvider – параметры командной строки.

Заметьте, что значения одного провайдера могут переписывать значения другого (например, значения из appsettings.json заменяются значениями из секретных данных или переменных среды). В выводе GetDebugView() будет присутствовать только конечное значение.

Применение
Информация, предоставляемая GetDebugView(), может быть очень полезной, когда вам нужно отладить проблему конфигурации в вашем приложении. Возможность точно увидеть, откуда берется значение конфигурации, крайне важно, когда что-то работает не так, как вы ожидаете.

Один из очевидных подходов - предоставить конечную точку в приложении ASP.NET Core, где вы можете запросить это представление. В следующем примере использован метод MapGet для предоставления простой конечной точки:
app.UseEndpoints(endpoints => {
if(env.IsDevelopment()) {
endpoints.MapGet("/debug-config", ctx => {
var config =
(Configuration as IConfigurationRoot)
.GetDebugView();
return ctx.Response.WriteAsync(config);
});
}
});

Источник: https://andrewlock.net/debugging-configuration-values-in-aspnetcore/
День восемьсот девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
84. Мыслите Состояниями
У людей в реальном мире странные понятия состояний. Утром я зашёл в кофейню, чтобы подготовиться к очередному дню преобразования кофеина в код (купить латте). Но девушка ответила: "Извините, у нас вообще, совсем нет никакого молока, ни капли."

С точки зрения программиста это странное заявление. Когда дело доходит до наличия или отсутствия молока, это нельзя измерить. Молоко либо закончилось, либо нет. Возможно, она пыталась сказать мне, что у них не будет молока всю неделю, но результат был бы тот же – сегодня я пью эспрессо.

В большинстве реальных ситуаций такая вольная трактовка состояний людьми не является проблемой. Но, к сожалению, многие программисты также неряшливо обращаются с состоянием программ. А это уже проблема.

Рассмотрим простой интернет-магазин, который работает только по предоплате. Класс заказа, может содержать такой метод:
public bool IsComplete() => IsPaid() && HasShipped();

Вроде логично. Но, даже если это выражение аккуратно извлечено в метод, а не продублировано повсюду, такого выражения не должно существовать вообще. Тот факт, что оно существует, говорит о проблеме. Почему? Потому что заказ не может быть отправлен до оплаты. Таким образом, HasShipped() не может быть true, если IsPaid() не true, что делает эту часть выражения избыточной. Возможно, вам всё равно нужен метод IsComplete() для ясности кода, но тогда он должен выглядеть так:
public bool IsComplete() => HasShipped();

В своей работе я постоянно встречаюсь как с недостаточными, так и с избыточными проверками. Этот пример крошечный, но, если добавить сюда отмену заказа и возврат денег, он станет более сложным, и потребность в хорошей обработке состояния возрастёт. В нашем случае заказ может находиться только в одном из трёх состояний:
- В обработке: можно добавлять или удалять элементы. Нельзя отправлять.
- Оплачен: нельзя добавлять или удалять элементы. Возможна отправка.
- Отправлен: Готово. Больше никакие изменения не доступны.

Эти состояния важны, т.к. нужно убедиться, что:
1. вы находитесь в ожидаемом состоянии, прежде чем выполнять операции,
2. вы можете перейти только в одно из доступных состояний.
То есть, вы должны тщательно защитить свои объекты в нужных местах.

Но как начать мыслить состояниями? Извлечение выражений в осмысленные методы - очень хорошее начало, но это только начало. Основа - понимание конечных автоматов. Я знаю, что у вас могут возникнуть плохие воспоминания об уроках информатики, гоните их прочь. Конечные автоматы не так трудны. Визуализируйте их, чтобы сделать их простыми для понимания и обсуждения. Протестируйте свой код, чтобы выявить допустимые и недопустимые состояния и переходы и сохранить их правильность. Изучите паттерн Состояние, почитайте про программирование по контракту. Оно поможет вам обеспечить допустимое состояние, проверяя входящие данные и сам объект при входе и при выходе из каждого публичного метода.

Если ваша программа находится в неправильном состоянии, - это ошибка, и вы рискуете испортить данные, если не прервёте операцию. Если вы обнаружите, что проверки состояния вносят в код слишком много шума, изучите возможности IDE, генераторы кода или аспектное программирование (weaving), чтобы скрыть их. Независимо от того, какой подход вы выберете, мышление состояниями сделает ваш код более простым и надёжным.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Niclas Nilsson
День восемьсот десятый. #ЧтоНовенького
.NET 6: Новые Структуры Даты и Времени
Давняя проблема библиотеки базовых классов .NET заключается в невозможности раздельного представления значений даты и времени. Новые структуры .NET 6 DateOnly и TimeOnly призваны исправить это упущение.

Как следует из названия, они предназначены для хранения только даты и только времени соответственно. Таким образом, они отвечают принципу SRP в том смысле, что не могут играть разные роли (раньше DateTime использовалась для хранения и только даты, и только времени, и даже интервалов).

Исходное имя структуры DateTime было просто Date. Это всё ещё справедливо для VB, где ключевое слово Date продолжает ссылаться на DateTime. Таким образом, название DateOnly было выбрано, чтобы избежать путаницы. Другая причина заключается в том, что DateTime.Date возвращает значение DateTime. Это уже нельзя изменить, но новички часто ожидают, что это свойство возвращает только дату. Поэтому новое свойство, возвращающее DateOnly, можно назвать DateTime.DateOnly.

Точно так же имя TimeOfDay проблематично, поскольку многие свойства и методы используют его для ссылки на значение DateTime или TimeSpan.

Сериализация
DateOnly и TimeOnly не будут реализовывать атрибут Serializable. В .NET Core и более поздних версиях этот атрибут считается устаревшим, как и библиотеки сериализации, которые на него полагаются.

Был запрос на атрибут IXmlSerializable и его эквивалент в для JSON. Однако DateOnly и TimeOnly должны быть помещены в одну из библиотек нижнего уровня NET, где такие атрибуты недоступны. Таким образом, сериализаторам необходимо будет включить собственную обработку этих новых типов. Такое же изменение придётся сделать и в драйверах баз данных.

Это может привести к тому, что после выпуска .NET 6 в течение какого-то времени нельзя будет использовать DateOnly и TimeOnly в некоторых сценариях, пока сериализаторы не подстроятся.

DateTimeOnly
Пытаясь решить проблему часового пояса, .NET 2 представила свойство DateTime.Kind. Разработчики имели возможность аннотировать свои значения даты и времени с помощью флага, указывающего, представляет ли значение местный часовой пояс, всемирное координированное время или неуказанный часовой пояс. На самом деле это привело к тому, что разработчики были вынуждены указывать эту информацию или сталкиваться с неожиданными ошибками.

Что еще хуже, свойство Kind использовалось непоследовательно. Например, многие сериализаторы, видя его, добавляли смещение при экспорте значения. Это приводило к трудно диагностируемым ошибкам, поскольку только некоторые даты (например, полученные из DateTime.Now) сериализовывались со смещением. А операторы сравнения полностью игнорировали Kind. Предполагалось, что разработчик сам проверит свойство Kind и при необходимости выполнит преобразование часового пояса.

Чтобы устранить эти проблемы, есть запрос на новую структуру DateTimeOnly, которая в основном работает так же, как DateTime в .NET 1 (т.е. дата и время без указания часового пояса).

Источник: https://www.infoq.com/news/2021/04/Net6-Date-Time/