Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1404. #ЧтоНовенького #DotNet8 Новые Анализаторы в .NET 8 .NET 7 вышел, пора посмотреть, что нас ждёт в новой версии))) Сегодня рассмотрим новые анализаторы кода. Анализаторы в версии превью можно использовать, если добавить в файл .csproj следующее:
<PropertyGroup Label="Analyzer settings">
  <AnalysisLevel>preview</AnalysisLevel>
</PropertyGroup>

Уже сейчас есть более 100 правил, которые предупредят вас в определённых ситуациях. Полный список можно найти на странице GitHub. Сегодня рассмотрим, что нового собираются добавить. Строки 1. Рекомендация заменить string.ToLower() на регистронезависимый Equals По сути, правило предложит заменить
str.ToLowerCase() == "string";
на
string.Equals(str, "string", StringComparison.OrdinalIgnoreCase);
Это быстрее и не аллоцирует строки. 2. Рекомендация использовать StartsWith вместо IndexOf == 0 Проблема с IndexOf в том, что в худшем случае он пройдёт по всей строке. StartsWith, напротив, сразу прервётся при первом несоответствии, поэтому он быстрее. Коллекции 3. Рекомендация использовать Length/Count/IsEmpty вместо Any() Если в коллекции есть свойство вроде Length (T[]), Count (List<T>) или IsEmpty (потокобезопасные коллекции), то лучше использовать его, а не Any().
// Это будет помечено новым анализатором
var isEmpty = names.Any();
// Это не будет помечено как "предпочтительное"
var isEmpty = names.Count != 0;
Это может быть быстрее, т.к. Any выполняет проверку типов, а Length или Count — это простые свойства, которые, помимо прочего, могут быть встроены. Хотя, субъективно, в коде Any может выглядеть более читабельно. 4. Предотвращение неправильного использования Split Допустим, вы хотите разделить строку по пробелам и табам:
var split = s.Split(' ', '\t');
Это прекрасно работает. Но если вы захотите удалить пустые элементы:
var split = s.Split(' ', '\t',
  StringSplitOptions.RemoveEmptyEntries);
Но это не будет работать правильно, потому что второй char преобразуется в int и будет использован в качестве аргумента count (максимального количества элементов в результирующем массиве) для перегруженной версии Split. Правильное использование будет таким:
var split = s.Split(new[] { ' ', '\t' },
  StringSplitOptions.RemoveEmptyEntries);

Структуры 6. Атрибут NonCopyable Обычно, если вы передаёте типы-значения в функцию, они копируются. В чём проблема? Предположим, вы пишете какой-то высокопроизводительный API (например, ValueStringBuilder), используя (ref) struct, чтобы избежать аллокаций на куче. Потребители этих типов должны быть осторожны, чтобы объект не копировался повсюду. И вот тут-то поможет новый атрибут.
[NonCopyable]
public ref struct ValueStringBuilder
{ … }

// Использование
public void MyMethod(ValueStringBuilder vsb)
{ … }

var vsb = new ValueStringBuilder();
MyMethod(vsb);

Здесь будет ошибка, т.к. ValueStringBuilder должен передаваться по ссылке. Правильное использование:
public void MyMethod(ref ValueStringBuilder vsb)
{ … }

var vsb = new ValueStringBuilder();
MyMethod(ref vsb);

Источник: https://steven-giesel.com/blogPost/1a03a998-e428-4a42-9c30-1cfbf6ac5f4c