День пятьсот сорок восьмой.
7 Опасных Ошибок, Которые Легко Совершить в C#/.NET. Продолжение 5-6
В каждом языке есть ловушки, в которые легко попасть и ошибочные представления об ожидаемом поведении языка. Вот некоторые из них.
Начало 1-2
Продолжение 3-4
5. Ужасный Класс "DBNull"
У некоторых это может вызвать неприятные воспоминания, т.к. ORM скрывает это зло от нас, но если вы используете чистый ADO.NET (
Я не уверен на 100%, почему в Microsoft решили представить
Разница может показаться незначительной, но значения
Единственное преимущество этого - вы не получите
6. Злоупотребление ленивой загрузкой в LINQ
Ленивая загрузка - это отличная функция как LINQ to SQL, так и LINQ to Entities (Entity Framework), которая позволяет загружать связанные данные таблицы по требованию. Допустим, у нас есть таблицы
Когда нужно получить данные определённого модуля, но не нужны относящиеся к нему результаты, Entity Framework достаточно умён, чтобы запросить данные только для модуля, а для получения результатов выполнить отдельный запрос, только когда они потребуются. Таким образом, приведенный ниже код будет выполнять как минимум 2 запроса: один для получения модуля, а другой для получения результатов (для каждого модуля).
Окончание следует…
Источник: https://chrisstclair.co.uk/7-dangerous-mistakes-in-c-net-that-are-easy-to-make/
7 Опасных Ошибок, Которые Легко Совершить в C#/.NET. Продолжение 5-6
В каждом языке есть ловушки, в которые легко попасть и ошибочные представления об ожидаемом поведении языка. Вот некоторые из них.
Начало 1-2
Продолжение 3-4
5. Ужасный Класс "DBNull"
У некоторых это может вызвать неприятные воспоминания, т.к. ORM скрывает это зло от нас, но если вы используете чистый ADO.NET (
SqlDataReader
и т.п.), вы рано или поздно столкнётесь с DBNull.Value
.Я не уверен на 100%, почему в Microsoft решили представить
NULL
в виде специального типа DBNull
со статическим полем Value
. Возможно, причина в обратной совместимости. Так было в Visual Basic в эпоху до .NET. VB6 не имеет унифицированной объектной модели (когда всё наследуется от System.Object
) или концепции «null». Существует Nothing
, но это скорее default
из C#, чем null
. Таким образом, в VB6 и ADO, у вас есть значение DBNull
для представления null
из БД.Разница может показаться незначительной, но значения
DBNull
и null
имеют разную семантику. Например, в строках. В VB нулевая строка равна пустой строке. Нет никакого способа разделить эти две концепции как в VB6, так и VB7+ (VB.NET).Единственное преимущество этого - вы не получите
NullReferenceException
при доступе к полю базы данных, равному NULL
. Однако при этом вы не только должны поддерживать отдельный способ проверки значений на NULL
(о чём можно легко забыть, и что может привести к серьезным ошибкам), но также вы теряете прекрасные возможности языка C#. Например, вместо:reader.GetString(0) ?? "NULL";придётся использовать:
reader.GetString(0) != DBNull.Value ? reader.GetString(0) : "NULL";Ужас!
6. Злоупотребление ленивой загрузкой в LINQ
Ленивая загрузка - это отличная функция как LINQ to SQL, так и LINQ to Entities (Entity Framework), которая позволяет загружать связанные данные таблицы по требованию. Допустим, у нас есть таблицы
Modules
и Results
с отношением «один ко многим» (модуль может иметь много результатов).Когда нужно получить данные определённого модуля, но не нужны относящиеся к нему результаты, Entity Framework достаточно умён, чтобы запросить данные только для модуля, а для получения результатов выполнить отдельный запрос, только когда они потребуются. Таким образом, приведенный ниже код будет выполнять как минимум 2 запроса: один для получения модуля, а другой для получения результатов (для каждого модуля).
using (var db = new DBEntities()) {Однако, если у нас много модулей, отдельный SQL запрос к результатам будет выполняться для каждого модуля. Очевидно, что это лишняя и ненужная нагрузка на сервер. Но в Entity Framework решить проблему очень легко, просто запросив включение результатов в исходный запрос:
var modules = db.Modules;
foreach (var module in modules) {
var moduleType = module.Results;
//Обработка модуля
}
}
var modules = db.Modules.Include(b => b.Results);В этом случае выполнится всего один SQL запрос, который будет включать все модули и все результаты для каждого модуля, что Entity Framework потом корректно транслирует в объекты модели.
Окончание следует…
Источник: https://chrisstclair.co.uk/7-dangerous-mistakes-in-c-net-that-are-easy-to-make/
День пятьсот сорок девятый.
Хороших выходных вам, дорогие подписчики. И вот вам видосик скрасить досуг первого дня авгрусти (запасайтесь двумя часами). На этот раз (большая редкость) видео на русском. Андрея Акиньшина в мире .NET лишний раз представлять не нужно. Его (по крайней мере, в русскоязычном сообществе) должны знать примерно как Рихтера или Скита. Впрочем, авторы видео его и не представляют, поэтому, если вы таки не знаете, кто это, сначала погуглите)))
В интервью каналу «Мы обречены» он рассказывает о своей книге «Pro .NET Benchmarking», про производительность и красоту кода, про хобби программистов и многое другое. В общем, лично мне очень понравилось.
Хороших выходных вам, дорогие подписчики. И вот вам видосик скрасить досуг первого дня авгрусти (запасайтесь двумя часами). На этот раз (большая редкость) видео на русском. Андрея Акиньшина в мире .NET лишний раз представлять не нужно. Его (по крайней мере, в русскоязычном сообществе) должны знать примерно как Рихтера или Скита. Впрочем, авторы видео его и не представляют, поэтому, если вы таки не знаете, кто это, сначала погуглите)))
В интервью каналу «Мы обречены» он рассказывает о своей книге «Pro .NET Benchmarking», про производительность и красоту кода, про хобби программистов и многое другое. В общем, лично мне очень понравилось.
YouTube
Андрей Акиньшин — бенчмарки, перфоманс, производительный код — Мы обречены #12
Супер-курс Влада Тена по Алгоритмам!
https://t.iss.one/tribute/app?startapp=sjGY-5jAPwCjfRH3
Чат подкаста в Телеграме — https://t.iss.one/myobrecheny
Телеграм канал — https://t.iss.one/myobrechenychannel
Твиттер — https://twitter.com/myobrecheny
VK — https://vk.com/myobrecheny…
https://t.iss.one/tribute/app?startapp=sjGY-5jAPwCjfRH3
Чат подкаста в Телеграме — https://t.iss.one/myobrecheny
Телеграм канал — https://t.iss.one/myobrechenychannel
Твиттер — https://twitter.com/myobrecheny
VK — https://vk.com/myobrecheny…
День пятьсот пятидесятый.
7 Опасных Ошибок, Которые Легко Совершить в C#/.NET. Окончание 7
В каждом языке есть ловушки, в которые легко попасть и ошибочные представления об ожидаемом поведении языка. Вот некоторые из них.
Начало 1-2
Продолжение 3-4
Продолжение 5-6
7. Непонимание Того как LINQ to SQL/Entity Framework Генерирует Запросы
Продолжая тему из пункта 6, стоит упомянуть, насколько по-разному будет выполняться ваш код, если он находится внутри запроса LINQ. Если коротко, весь код внутри запроса LINQ транслируется в SQL. Это кажется очевидным, но очень легко забыть контекст, в котором вы находитесь и допустить ошибку. Ниже приведён список некоторых типичных проблем, с которыми вы можете столкнуться.
Большинство методов не будут работать
Представьте, что вы используете следующий запрос, чтобы разделить имя модулей по двоеточию и захватить вторую часть:
Методы, которые всё же сработают, могут дать неожиданные результаты…
Рассмотрим следующее выражение LINQ (понятия не имею, зачем это делать на практике, но просто допустим, что надо):
Знайте, когда надо просто использовать старый добрый SQL.
Если вы выполняете чрезвычайно сложный запрос в LINQ, то автоматически сгенерированный SQL запрос может выглядеть как что-то, что съели, выплюнули, снова съели и снова выплюнули. К сожалению, конкретных примеров у меня нет, но, по опыту, использование сложных запросов к нескольким связанным таблицам превращает их поддержку в кошмар. Кроме того, могут появиться проблемы с производительностью, которые будет сложно решить, не имея прямого контроля над сгенерированным SQL. Поэтому либо напишите запрос сразу на SQL, либо доверьте эту работу администратору базы данных (если он у вас есть).
Источник: https://chrisstclair.co.uk/7-dangerous-mistakes-in-c-net-that-are-easy-to-make/
7 Опасных Ошибок, Которые Легко Совершить в C#/.NET. Окончание 7
В каждом языке есть ловушки, в которые легко попасть и ошибочные представления об ожидаемом поведении языка. Вот некоторые из них.
Начало 1-2
Продолжение 3-4
Продолжение 5-6
7. Непонимание Того как LINQ to SQL/Entity Framework Генерирует Запросы
Продолжая тему из пункта 6, стоит упомянуть, насколько по-разному будет выполняться ваш код, если он находится внутри запроса LINQ. Если коротко, весь код внутри запроса LINQ транслируется в SQL. Это кажется очевидным, но очень легко забыть контекст, в котором вы находитесь и допустить ошибку. Ниже приведён список некоторых типичных проблем, с которыми вы можете столкнуться.
Большинство методов не будут работать
Представьте, что вы используете следующий запрос, чтобы разделить имя модулей по двоеточию и захватить вторую часть:
var modules = from m in db.ModulesЭто вызовет исключение в большинстве провайдеров LINQ: для метода
select m.Name.Split(':')[1];
Split
нет перевода в SQL. Могут поддерживаться некоторые методы, например, добавление дней к дате, но всё зависит от провайдера.Методы, которые всё же сработают, могут дать неожиданные результаты…
Рассмотрим следующее выражение LINQ (понятия не имею, зачем это делать на практике, но просто допустим, что надо):
int modules = db.Modules.Sum(a => a.ID);Если строки в таблице Modules есть, то выражение выдаст сумму значений идентификаторов. Вроде всё правильно. Но что, если применить это выражение к LINQ to Objects? Мы можем сделать это, преобразовав коллекцию модулей в список перед вызовом метода
Sum
:int modules = db.Modules.ToList().Sum(a => a.ID);И ВНЕЗАПНО!… мы получим тот же ответ. Однако, если строк в таблице не будет, то LINQ to Objects вернёт
0
, а версия для Entity Framework/LINQ to SQL выдаст исключение InvalidOperationException
, сообщающее, что невозможно преобразовать int?
в int
. Это связано с тем, что вызов SUM
в SQL на пустом наборе вместо 0
возвращает NULL
. Следовательно, вместо этого он пытается вернуть обнуляемый тип int
. Поэтому…Знайте, когда надо просто использовать старый добрый SQL.
Если вы выполняете чрезвычайно сложный запрос в LINQ, то автоматически сгенерированный SQL запрос может выглядеть как что-то, что съели, выплюнули, снова съели и снова выплюнули. К сожалению, конкретных примеров у меня нет, но, по опыту, использование сложных запросов к нескольким связанным таблицам превращает их поддержку в кошмар. Кроме того, могут появиться проблемы с производительностью, которые будет сложно решить, не имея прямого контроля над сгенерированным SQL. Поэтому либо напишите запрос сразу на SQL, либо доверьте эту работу администратору базы данных (если он у вас есть).
Источник: https://chrisstclair.co.uk/7-dangerous-mistakes-in-c-net-that-are-easy-to-make/
День пятьсот пятьдесят первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
53. Модульные тесты - пустая трата времени?
Модульные тесты - пустая трата времени: вы всегда будете тратить больше усилий на их поддержку, чем на написание кода.
- Кто-то, в какой-то момент вашей карьеры
Я слышал это десятки раз. Обычно веб-разработчики более склонны так думать, чем их бэкенд-коллеги. И на то есть веская причина: юнит-тестам фронтэнда ещё есть куда расти. В последние годы мне посчастливилось запустить большое количество новых проектов, больших и малых, и, оглядываясь назад, я чувствую, что написание тестов всегда экономило время (или могло бы сэкономить). Но мне потребовалось много времени, чтобы по-настоящему понять их преимущества и изменить свои привычки. Есть много тех, кто до сих пор скептически относится к юнит-тестам, но вот что лично я бы сказал молодому себе: «Забудь про фразу "не хватает времени для написания модульных тестов"».
Вы никогда не напишите их «позже», вам нужна дисциплина, чтобы сделать это, и если у вас их нет по мере написания кода, у вас наверняка не будет их никогда, поскольку проект становится больше и больше. Ни один проект не может быть слишком мал, чтобы его не тестировать. По своему опыту скажу, что для всего, что длиннее 5 строк кода, тестирование вручную всегда будет дороже автоматизированного.
Со временем вы обнаружите, что, когда вы делаете свой код тестируемым, вы также повышаете его внутреннее качество. Помните тот момент, когда вы тратили несколько часов, чтобы воспроизвести какую-нибудь странную ошибку? Программные системы сложны и требуют идеального взаимодействия многих элементов, некоторые из которых находятся вне вашего контроля. Если что-то идёт не так только в редком случае, когда какой-то внешний модуль возвращает что-то неожиданное, отладка становится практически невозможной. Поскольку модульные тесты позволяют вам контролировать состояние вашего приложения в мельчайших деталях, воспроизведение такой проблемы становится намного проще.
Модульное тестирование - это не какая-то дополнительная фича, которую хорошо бы иметь. Это обязательный шаг в процессе разработки программного обеспечения. Как команда инженеров, вы можете пропустить их, но это рано или поздно отбросит вас назад и будет стоить вам кучу времени. В конце концов, а какие есть другие варианты?
1. Не тестировать вообще. Излишне говорить, что полученный продукт будет бесполезным дерьмом. Вы должны будете исправлять его исключительно на основании отзывов пользователей, что приведёт к непостижимым затратам и поиску другой работы.
2. Отдать продукт на ручное тестирование другой команде. Достаточно скоро вы обнаружите, что проблемы, которые в противном случае вы могли бы обнаружить довольно быстро, будут продолжать возникать между вами и тестерами. Это уже лучше: по крайней мере ваши пользователи больше не проводят тестирование за вас. Тем не менее, постоянный пинг-понг тикетами с тестировщиками отнимает много времени, плюс с каждой итерацией вам придётся перезапускать весь процесс.
3. Вы вручную тестируете свой код перед тем, как передать его по дальше. Это, наверное, самый распространенный сценарий (по крайней мере, я на это надеюсь). Вы наверняка думаете, что как разработчик вы хорошо знаете, где найти проблему и быстро её исправить. Однако, учитывая, насколько сложным может быть состояние приложения и насколько долго иногда приходится воссоздавать все необходимые условия для репликации проблемы, в конце концов вы потратите уйму времени, не на исправление ошибки, а тыкая по кнопкам, воспроизводя путь пользователя.
Да, модульное тестирование в любом случае отнимает много времени, особенно если у вас плохо спроектирована кодовая база. Но вам всё равно придётся тестировать свой код. Единственный выбор, который перед вами стоит, - тратить время, выполняя тесты вручную, или инвестировать некоторые усилия в обучение правильному написанию модульных тестов и получать выгоду позже.
Источник: https://hackernoon.com/are-unit-tests-a-waste-of-your-time-ftw3umv
97 Вещей, Которые Должен Знать Каждый Программист
53. Модульные тесты - пустая трата времени?
Модульные тесты - пустая трата времени: вы всегда будете тратить больше усилий на их поддержку, чем на написание кода.
- Кто-то, в какой-то момент вашей карьеры
Я слышал это десятки раз. Обычно веб-разработчики более склонны так думать, чем их бэкенд-коллеги. И на то есть веская причина: юнит-тестам фронтэнда ещё есть куда расти. В последние годы мне посчастливилось запустить большое количество новых проектов, больших и малых, и, оглядываясь назад, я чувствую, что написание тестов всегда экономило время (или могло бы сэкономить). Но мне потребовалось много времени, чтобы по-настоящему понять их преимущества и изменить свои привычки. Есть много тех, кто до сих пор скептически относится к юнит-тестам, но вот что лично я бы сказал молодому себе: «Забудь про фразу "не хватает времени для написания модульных тестов"».
Вы никогда не напишите их «позже», вам нужна дисциплина, чтобы сделать это, и если у вас их нет по мере написания кода, у вас наверняка не будет их никогда, поскольку проект становится больше и больше. Ни один проект не может быть слишком мал, чтобы его не тестировать. По своему опыту скажу, что для всего, что длиннее 5 строк кода, тестирование вручную всегда будет дороже автоматизированного.
Со временем вы обнаружите, что, когда вы делаете свой код тестируемым, вы также повышаете его внутреннее качество. Помните тот момент, когда вы тратили несколько часов, чтобы воспроизвести какую-нибудь странную ошибку? Программные системы сложны и требуют идеального взаимодействия многих элементов, некоторые из которых находятся вне вашего контроля. Если что-то идёт не так только в редком случае, когда какой-то внешний модуль возвращает что-то неожиданное, отладка становится практически невозможной. Поскольку модульные тесты позволяют вам контролировать состояние вашего приложения в мельчайших деталях, воспроизведение такой проблемы становится намного проще.
Модульное тестирование - это не какая-то дополнительная фича, которую хорошо бы иметь. Это обязательный шаг в процессе разработки программного обеспечения. Как команда инженеров, вы можете пропустить их, но это рано или поздно отбросит вас назад и будет стоить вам кучу времени. В конце концов, а какие есть другие варианты?
1. Не тестировать вообще. Излишне говорить, что полученный продукт будет бесполезным дерьмом. Вы должны будете исправлять его исключительно на основании отзывов пользователей, что приведёт к непостижимым затратам и поиску другой работы.
2. Отдать продукт на ручное тестирование другой команде. Достаточно скоро вы обнаружите, что проблемы, которые в противном случае вы могли бы обнаружить довольно быстро, будут продолжать возникать между вами и тестерами. Это уже лучше: по крайней мере ваши пользователи больше не проводят тестирование за вас. Тем не менее, постоянный пинг-понг тикетами с тестировщиками отнимает много времени, плюс с каждой итерацией вам придётся перезапускать весь процесс.
3. Вы вручную тестируете свой код перед тем, как передать его по дальше. Это, наверное, самый распространенный сценарий (по крайней мере, я на это надеюсь). Вы наверняка думаете, что как разработчик вы хорошо знаете, где найти проблему и быстро её исправить. Однако, учитывая, насколько сложным может быть состояние приложения и насколько долго иногда приходится воссоздавать все необходимые условия для репликации проблемы, в конце концов вы потратите уйму времени, не на исправление ошибки, а тыкая по кнопкам, воспроизводя путь пользователя.
Да, модульное тестирование в любом случае отнимает много времени, особенно если у вас плохо спроектирована кодовая база. Но вам всё равно придётся тестировать свой код. Единственный выбор, который перед вами стоит, - тратить время, выполняя тесты вручную, или инвестировать некоторые усилия в обучение правильному написанию модульных тестов и получать выгоду позже.
Источник: https://hackernoon.com/are-unit-tests-a-waste-of-your-time-ftw3umv
День пятьсот пятьдесят второй. #ЧтоНовенького
Новые Функции в Visual Studio для Повышения Продуктивности. Начало
Команда Roslyn представляет новые функции для повышения продуктивности в Visual Studio 2019.
1. Автодополнения IntelliSense для форматов DateTime и TimeSpan. Эта обещает быть чрезвычайно полезным, потому что мы все знаем, как сложно запоминать форматы даты и времени. Поместите курсор в строковый литерал
2. Добавление заголовка файла позволяет легко добавлять заголовки к существующим файлам, проектам и решениям с помощью EditorConfig. Добавьте правило
3. Диалоговое окно изменения сигнатуры метода теперь позволит добавлять параметры. Поместите курсор на сигнатуру метода и
Источник: https://devblogs.microsoft.com/dotnet/learn-about-the-latest-net-productivity-features/
Новые Функции в Visual Studio для Повышения Продуктивности. Начало
Команда Roslyn представляет новые функции для повышения продуктивности в Visual Studio 2019.
1. Автодополнения IntelliSense для форматов DateTime и TimeSpan. Эта обещает быть чрезвычайно полезным, потому что мы все знаем, как сложно запоминать форматы даты и времени. Поместите курсор в строковый литерал
DateTime
или TimeSpan
и нажмите (Ctrl+Пробел
). Вы увидите варианты завершения и объяснение, что означает каждый символ. См. рис.1 ниже.2. Добавление заголовка файла позволяет легко добавлять заголовки к существующим файлам, проектам и решениям с помощью EditorConfig. Добавьте правило
file_header_template
в файл .editorconfig
и установите нужный текст заголовка. Затем поместите курсор в первую строку любого файла C#. Нажмите Ctrl+.
, чтобы вызвать меню «Быстрые действия и рефакторинг», и выберите «Добавить заголовок файла» («Add file header»). См. рис.2 ниже.3. Диалоговое окно изменения сигнатуры метода теперь позволит добавлять параметры. Поместите курсор на сигнатуру метода и
Ctrl+.
, чтобы вызвать меню «Быстрые действия и рефакторинг», и выберите «Изменить сигнатуру» («Change signature»). Откроется окно, где вы можете нажать «Добавить» («Add») для добавления параметра. При этом откроется новое диалоговое окно «Добавить Параметр» («Add Parameter»). См. рис.3 ниже. Оно позволяет задать тип и имя параметра, а также сделать параметр обязательным или необязательным со значением по умолчанию. Кроме того, вы можете задать значение в вызывающем коде (по желанию использовав именованный аргумент для этого значения), либо ввести переменную TODO. Переменная TODO поместит «TODO
» в вызывающий код, чтобы вы могли обойти все вызовы метода и передать нужное значение в каждом случае. Для необязательных параметров есть возможность пропустить изменения в вызывающем коде.Источник: https://devblogs.microsoft.com/dotnet/learn-about-the-latest-net-productivity-features/
День пятьсот пятьдесят третий. #юмор
Примерно так же надо задавать вопрос на Stackoverflow)))
Примерно так же надо задавать вопрос на Stackoverflow)))
День пятьсот пятьдесят четвёртый. #ЧтоНовенького
Новые Функции в Visual Studio для Повышения Продуктивности. Окончание
Начало
Исправления и рефакторинг кода - это предложения по изменению кода, которые компилятор предоставляет с помощью значков лампочки и отвертки. Чтобы вызвать меню быстрых действий и рефакторинга, нажмите Ctrl+. или Alt+Enter. Команда Roslyn представляет новые возможности исправления и рефакторинга кода в Visual Studio 2019:
- Добавление явного приведения (Add explicit cast). Позволяет добавить оператор явного приведения, если неявное приведение выражения невозможно. См. рис. 1 ниже.
- Упрощение условного выражения (Simplify conditional expression). Делает условные выражения более чёткими и краткими. См. рис. 2 ниже.
- Преобразование в дословную/обычную строку (Convert To Verbatim/Regular String). Позволяет в одно нажатие преобразовать строку из обычной в дословную и наоборот. См. рис. 3 ниже.
- Добавление атрибута «DebuggerDisplay» (Add ‘DebuggerDisplay’ attribute). Предложение появляется, если поместить курсор на имя класса. Позволяет программно закреплять свойства в отладчике кода. Добавляет атрибут отображения в отладчике в начало класса и генерирует автоматический метод, который возвращает
- Генерация операторов сравнения (Generate comparison operators). Генерирует шаблонный код с операторами сравнения для типов, реализующих
- Генерация операторов IEquatable (Generate Equals(object)). Добавляет реализацию
- Генерация конструктора со свойствами (Generate constructor in <QualifiedName> (with properties)). Предложение появляется, если поместить курсор на экземпляр типа. Позволяет добавить в соответствующий тип конструктор нужной сигнатуры и необходимые свойства. См. рис. 7 ниже.
- Исправление случайных присвоений и сравнений (Assign/Compare to '<QualifiedName>.value'). Позволяет исправить операцию присвоения или сравнения, когда имена поля класса и параметра конструктора совпадают. Исправление добавляет “
Источник: https://devblogs.microsoft.com/dotnet/learn-about-the-latest-net-productivity-features/
Новые Функции в Visual Studio для Повышения Продуктивности. Окончание
Начало
Исправления и рефакторинг кода - это предложения по изменению кода, которые компилятор предоставляет с помощью значков лампочки и отвертки. Чтобы вызвать меню быстрых действий и рефакторинга, нажмите Ctrl+. или Alt+Enter. Команда Roslyn представляет новые возможности исправления и рефакторинга кода в Visual Studio 2019:
- Добавление явного приведения (Add explicit cast). Позволяет добавить оператор явного приведения, если неявное приведение выражения невозможно. См. рис. 1 ниже.
- Упрощение условного выражения (Simplify conditional expression). Делает условные выражения более чёткими и краткими. См. рис. 2 ниже.
- Преобразование в дословную/обычную строку (Convert To Verbatim/Regular String). Позволяет в одно нажатие преобразовать строку из обычной в дословную и наоборот. См. рис. 3 ниже.
- Добавление атрибута «DebuggerDisplay» (Add ‘DebuggerDisplay’ attribute). Предложение появляется, если поместить курсор на имя класса. Позволяет программно закреплять свойства в отладчике кода. Добавляет атрибут отображения в отладчике в начало класса и генерирует автоматический метод, который возвращает
ToString()
. Метод можно отредактировать, чтобы вернуть значение свойства, которое вы хотите закрепить в отладчике. См. рис. 4 ниже.- Генерация операторов сравнения (Generate comparison operators). Генерирует шаблонный код с операторами сравнения для типов, реализующих
IComparable
. См. рис. 5 ниже.- Генерация операторов IEquatable (Generate Equals(object)). Добавляет реализацию
IEquatable
, а также операторы равенства и не равенства для структур. См. рис. 6 ниже.- Генерация конструктора со свойствами (Generate constructor in <QualifiedName> (with properties)). Предложение появляется, если поместить курсор на экземпляр типа. Позволяет добавить в соответствующий тип конструктор нужной сигнатуры и необходимые свойства. См. рис. 7 ниже.
- Исправление случайных присвоений и сравнений (Assign/Compare to '<QualifiedName>.value'). Позволяет исправить операцию присвоения или сравнения, когда имена поля класса и параметра конструктора совпадают. Исправление добавляет “
this.
” в нужную часть операции. См. рис. 8 ниже.Источник: https://devblogs.microsoft.com/dotnet/learn-about-the-latest-net-productivity-features/
День пятьсот пятьдесят пятый. #DotNetAZ
Dotnet A-Z. 5
В этой серии постов рассмотрим наиболее распространённые понятия в .NET в алфавитном порядке.
Mono
Mono - это кроссплатформенная реализация .NET с открытым исходным кодом, которая в основном используется, когда требуется небольшая среда выполнения. Это среда выполнения, которая поддерживает приложения Xamarin на Android, Mac, iOS, tvOS и watchOS и ориентирована в первую очередь на приложения, чувствительные к размеру исполняемого файла.
Mono поддерживает все опубликованные в настоящее время версии .NET Standard. Исторически Mono реализовывал более крупный API .NET Framework и эмулировал некоторые из самых популярных возможностей Unix. Иногда он используется для запуска приложений .NET, которые полагаются на эти возможности в Unix. Mono обычно используется совместно с JIT-компилятором, но он также имеет полноценный AOT-компилятор, который используется например в iOS.
Документация Mono
.NET
Общий термин для .NET Standard и всех реализаций .NET. Термин всегда пишется всеми заглавными буквами.
Документация .NET
.NET Core
Кросс-платформенная, высокопроизводительная реализация .NET с открытым исходным кодом. Включает в себя Core Common Language Runtime (CoreCLR), Core AOT Runtime (CoreRT, находится в разработке), библиотеку базовых классов Core BCL и набор средств разработки Core SDK.
Документация .NET Core
.NET Core CLI (Интерфейс Командной Строки)
Кросс-платформенный набор инструментов для разработки приложений .NET Core.
Обзор .NET Core CLI
.NET Core SDK (Набор Средств Разработки)
Набор библиотек и инструментов, позволяющих разработчикам создавать приложения и библиотеки .NET Core. Включает .NET Core CLI для создания приложений, библиотеки .NET Core и среду выполнения для создания и запуска приложений, а также исполняемый файл
Обзор .NET Core SDK
.NET Framework
Реализация .NET, работающая только в Windows. Включает общеязыковую среду выполнения (CLR), библиотеку базовых классов и библиотеки фреймворков приложений, такие как ASP.NET, Windows Forms и WPF.
Документация .NET Framework
.NET Native
Цепочка инструментов AOT-компиляции. Компиляция происходит на машине разработчика аналогично тому, как работают компилятор и компоновщик в C++. Компилятор удаляет неиспользуемый код и тратит больше времени на оптимизацию. Он извлекает код из библиотек и объединяет их в исполняемый файл. В результате получается один модуль, представляющий всё приложение.
UWP была первой платформой приложений, поддерживаемой .NET Native. Теперь поддерживается создание нативных консольных приложений для Windows, macOS и Linux.
.NET Standard
Формальная спецификация API .NET, доступных в каждой реализации .NET. Спецификацию .NET Standard в документации иногда называют библиотекой. Но поскольку библиотека включает в себя реализации API, а не только спецификации (интерфейсы), называть .NET Standard «библиотекой» неправильно.
Документация .NET Standard
Источник: https://docs.microsoft.com/en-us/dotnet/standard/glossary
Dotnet A-Z. 5
В этой серии постов рассмотрим наиболее распространённые понятия в .NET в алфавитном порядке.
Mono
Mono - это кроссплатформенная реализация .NET с открытым исходным кодом, которая в основном используется, когда требуется небольшая среда выполнения. Это среда выполнения, которая поддерживает приложения Xamarin на Android, Mac, iOS, tvOS и watchOS и ориентирована в первую очередь на приложения, чувствительные к размеру исполняемого файла.
Mono поддерживает все опубликованные в настоящее время версии .NET Standard. Исторически Mono реализовывал более крупный API .NET Framework и эмулировал некоторые из самых популярных возможностей Unix. Иногда он используется для запуска приложений .NET, которые полагаются на эти возможности в Unix. Mono обычно используется совместно с JIT-компилятором, но он также имеет полноценный AOT-компилятор, который используется например в iOS.
Документация Mono
.NET
Общий термин для .NET Standard и всех реализаций .NET. Термин всегда пишется всеми заглавными буквами.
Документация .NET
.NET Core
Кросс-платформенная, высокопроизводительная реализация .NET с открытым исходным кодом. Включает в себя Core Common Language Runtime (CoreCLR), Core AOT Runtime (CoreRT, находится в разработке), библиотеку базовых классов Core BCL и набор средств разработки Core SDK.
Документация .NET Core
.NET Core CLI (Интерфейс Командной Строки)
Кросс-платформенный набор инструментов для разработки приложений .NET Core.
Обзор .NET Core CLI
.NET Core SDK (Набор Средств Разработки)
Набор библиотек и инструментов, позволяющих разработчикам создавать приложения и библиотеки .NET Core. Включает .NET Core CLI для создания приложений, библиотеки .NET Core и среду выполнения для создания и запуска приложений, а также исполняемый файл
dotnet
(dotnet.exe
), который выполняет команды CLI и запускает приложения.Обзор .NET Core SDK
.NET Framework
Реализация .NET, работающая только в Windows. Включает общеязыковую среду выполнения (CLR), библиотеку базовых классов и библиотеки фреймворков приложений, такие как ASP.NET, Windows Forms и WPF.
Документация .NET Framework
.NET Native
Цепочка инструментов AOT-компиляции. Компиляция происходит на машине разработчика аналогично тому, как работают компилятор и компоновщик в C++. Компилятор удаляет неиспользуемый код и тратит больше времени на оптимизацию. Он извлекает код из библиотек и объединяет их в исполняемый файл. В результате получается один модуль, представляющий всё приложение.
UWP была первой платформой приложений, поддерживаемой .NET Native. Теперь поддерживается создание нативных консольных приложений для Windows, macOS и Linux.
.NET Standard
Формальная спецификация API .NET, доступных в каждой реализации .NET. Спецификацию .NET Standard в документации иногда называют библиотекой. Но поскольку библиотека включает в себя реализации API, а не только спецификации (интерфейсы), называть .NET Standard «библиотекой» неправильно.
Документация .NET Standard
Источник: https://docs.microsoft.com/en-us/dotnet/standard/glossary
День пятьсот пятьдесят шестой. #ЗаметкиНаПолях
Асинхронный Mетод без async в C#
Недавно я изменил сигнатуру метода действия контроллера следующим образом:
Итак, мы можем безопасно опустить
Вы всегда можете ожидать
Подробнее про работу async/await
Удаление ключевых слов
Ловушки отсутствия async/await
1. Отсутствие методов в трассировке стека
Рассмотрим следующую цепочку методов:
Код ниже приводит к ошибке
Итого
В общем случая я бы не рекомендовал удалять async/await. Как говорится, преждевременная оптимизация - это корень зла. Можно рассмотреть удаление ключевых слов, если:
- Асинхронный метод - это просто звено в цепочке вызовов.
- Метод находится на «горячем» участке кода.
Источник: https://drakelambert.dev/2020/07/Asynchronous-Method-Without-async-in-C%23
Асинхронный Mетод без async в C#
Недавно я изменил сигнатуру метода действия контроллера следующим образом:
public async Task GetRecordAsync(int id) => await repo.GetAsync(id);
наpublic Task GetRecordAsync(int id) => repo.GetAsync(id);
Во время код-ревью члены моей команды быстро заметили это и поставили под сомнение удаление ключевых слов async
и await
. Сначала я согласился, что это выглядит сомнительно. Даже после объяснения, которое приведено ниже, может быть полезно их вернуть, чтобы другие на этом не спотыкались.Итак, мы можем безопасно опустить
async
/await
, поскольку вызывающий метод GetRecordAsync
в конечном итоге возвращает то же, что и вызываемый, repo.GetAsync
. Вместо того, чтобы наш метод ожидал завершения задачи и возвращал результат, он передаёт эту работу вызывающей стороне.Вы всегда можете ожидать
Task
, потому что он предоставляет API обратного вызова, который позволяет платформе сообщать, какой код выполнять после завершения асинхронной операции.Подробнее про работу async/await
Удаление ключевых слов
async
/await
предотвращает создание конечного автомата. Это немного снижает накладные расходы на выполнение метода. Хотя я не удивлюсь, если компилятор достаточно умён, чтобы оптимизировать этот момент.Ловушки отсутствия async/await
1. Отсутствие методов в трассировке стека
Рассмотрим следующую цепочку методов:
static async Task Top() => await Middle();
static Task Middle() => Bottom();
static async Task Bottom() {
await Task.Delay(10);
throw new Exception("Bottom Exception");
}
При вызове Top()
, трассировка стека не будет включать вызов Middle()
:System.Exception: Bottom Exception
at ConsoleApp1.Bottom()
at ConsoleApp1.Top()
at ConsoleApp1.Program.Main(String[] args)
2. Отмена Заданий при Использовании usingКод ниже приводит к ошибке
TaskCanceledException
:Task<string> Using HttpClient() {
using var client = new HttpClient();
return client.GetStringAsync("https://1.1.1.1");
}
Это происходит потому, что объект HttpClient
удаляется до того, как завершается асинхронный запрос, тем самым отменяя все текущие запросы.Итого
В общем случая я бы не рекомендовал удалять async/await. Как говорится, преждевременная оптимизация - это корень зла. Можно рассмотреть удаление ключевых слов, если:
- Асинхронный метод - это просто звено в цепочке вызовов.
- Метод находится на «горячем» участке кода.
Источник: https://drakelambert.dev/2020/07/Asynchronous-Method-Without-async-in-C%23
День пятьсот пятьдесят седьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
54. Долговечность Временных Решений
Почему мы создаём временные решения? Обычно возникает некоторая проблема, требующая срочного решения. Может внутренняя (например, нехватка нужного разработчикам инструмента), может внешняя, видимая конечным пользователям («костыль», исправляющий недостатки функционала).
В большинстве систем и команд вы найдете какое-нибудь ПО, которому не место в системе, которое считается черновиком, которое когда-нибудь будет изменено, которое не соответствует стандартам и руководствам, которым соответствует остальной код. Вы неизбежно услышите жалобы разработчиков на него. Причины его создания многочисленны и разнообразны, но ключ к успеху временного решения прост: оно работает.
Однако с временными решениями возникает проблема. Поскольку они есть, они так или иначе решают проблему, то нет необходимости делать что-то ещё. Всякий раз, когда руководитель расставляет задачи по приоритетам, многие из них будут более важны, чем надлежащая интеграция временного решения. Почему? Потому что оно есть, оно работает, и все смирились с его существованием. Единственным недостатком является то, что оно не следует выбранным стандартам и рекомендациям. Но, за редким исключением, это не воспринимается как трагедия.
Таким образом, временное решение остаётся. Навсегда. И если с ним возникнут проблемы, маловероятно, что будет решено переписать его в соответствии со стандартами. Скорее всего будет сделано быстрое временное обновление этого временного решения.
Это проблема? Ответ зависит от вашего проекта и от вашей личной заинтересованности в стандартах производственного кода. Когда система содержит слишком много временных решений, её энтропия или внутренняя сложность возрастают, а ремонтопригодность снижается. Однако это, вероятно, не главный вопрос. Помните, что мы говорим о решении проблемы. Оно вряд ли вам нравится - вряд ли оно вообще кому-нибудь нравится - но мотивации переделывать его немного.
Так что же делать, когда мы сталкиваемся с проблемой?
1. Избегать временных решений вообще.
Во многих случаях это просто невозможно. Есть актуальная проблема, которую нужно решить, а стандарты оказались слишком жесткими. Вы можете потратить немного сил, попытавшись изменить стандарты. Благородное, но утомительное занятие, кроме того, это изменение не принесёт результата в смысле решения вашей проблемы.
2. Повлиять на решения руководителя проекта.
Бизнес-процессы и процессы принятия решений зачастую консервативны и сопротивляются изменениям. Попытка может быть успешной в небольших проектах (особенно личных): вы просто решаете убрать беспорядок, никого не спрашивая. Также можно добиться успеха, если в проекте такой бардак, что дальше это терпеть невозможно, тогда обычно выделяется некоторое время на очистку проекта.
3. Если не делать ни первое, ни второе, всё останется, как есть.
Вам придётся решать множество проблем. Некоторые решения будут временными, большинство - практичными. Лучший способ борьбы с временными решениями - сделать их заведомо избыточными, чтобы потом предоставить более элегантное и полезное решение. Да пребудут с вами спокойствие в принятии того, что вы не можете изменить, смелость изменять то, что можете, и мудрость, чтобы отличать одно от другого.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Klaus Marquardt.
97 Вещей, Которые Должен Знать Каждый Программист
54. Долговечность Временных Решений
Почему мы создаём временные решения? Обычно возникает некоторая проблема, требующая срочного решения. Может внутренняя (например, нехватка нужного разработчикам инструмента), может внешняя, видимая конечным пользователям («костыль», исправляющий недостатки функционала).
В большинстве систем и команд вы найдете какое-нибудь ПО, которому не место в системе, которое считается черновиком, которое когда-нибудь будет изменено, которое не соответствует стандартам и руководствам, которым соответствует остальной код. Вы неизбежно услышите жалобы разработчиков на него. Причины его создания многочисленны и разнообразны, но ключ к успеху временного решения прост: оно работает.
Однако с временными решениями возникает проблема. Поскольку они есть, они так или иначе решают проблему, то нет необходимости делать что-то ещё. Всякий раз, когда руководитель расставляет задачи по приоритетам, многие из них будут более важны, чем надлежащая интеграция временного решения. Почему? Потому что оно есть, оно работает, и все смирились с его существованием. Единственным недостатком является то, что оно не следует выбранным стандартам и рекомендациям. Но, за редким исключением, это не воспринимается как трагедия.
Таким образом, временное решение остаётся. Навсегда. И если с ним возникнут проблемы, маловероятно, что будет решено переписать его в соответствии со стандартами. Скорее всего будет сделано быстрое временное обновление этого временного решения.
Это проблема? Ответ зависит от вашего проекта и от вашей личной заинтересованности в стандартах производственного кода. Когда система содержит слишком много временных решений, её энтропия или внутренняя сложность возрастают, а ремонтопригодность снижается. Однако это, вероятно, не главный вопрос. Помните, что мы говорим о решении проблемы. Оно вряд ли вам нравится - вряд ли оно вообще кому-нибудь нравится - но мотивации переделывать его немного.
Так что же делать, когда мы сталкиваемся с проблемой?
1. Избегать временных решений вообще.
Во многих случаях это просто невозможно. Есть актуальная проблема, которую нужно решить, а стандарты оказались слишком жесткими. Вы можете потратить немного сил, попытавшись изменить стандарты. Благородное, но утомительное занятие, кроме того, это изменение не принесёт результата в смысле решения вашей проблемы.
2. Повлиять на решения руководителя проекта.
Бизнес-процессы и процессы принятия решений зачастую консервативны и сопротивляются изменениям. Попытка может быть успешной в небольших проектах (особенно личных): вы просто решаете убрать беспорядок, никого не спрашивая. Также можно добиться успеха, если в проекте такой бардак, что дальше это терпеть невозможно, тогда обычно выделяется некоторое время на очистку проекта.
3. Если не делать ни первое, ни второе, всё останется, как есть.
Вам придётся решать множество проблем. Некоторые решения будут временными, большинство - практичными. Лучший способ борьбы с временными решениями - сделать их заведомо избыточными, чтобы потом предоставить более элегантное и полезное решение. Да пребудут с вами спокойствие в принятии того, что вы не можете изменить, смелость изменять то, что можете, и мудрость, чтобы отличать одно от другого.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Klaus Marquardt.