🛠️ Пример параметризованного теста xUnit
Вместо того, чтобы добавлять множество различных тестовых методов с разными входными данными, заданными в теле метода, мы создаем один метод, передаем в него входные данные и ожидаемые результаты для каждого теста в виде параметров.
Это означает меньшее количество тестовых методов (что упрощает изменение логики тестов) и возможность быстро увидеть все входные данные и ожидаемые результаты для конкретного метода вместе.
В примере используется атрибут
#dotnet #csharp #tip by Dave Callan
Вместо того, чтобы добавлять множество различных тестовых методов с разными входными данными, заданными в теле метода, мы создаем один метод, передаем в него входные данные и ожидаемые результаты для каждого теста в виде параметров.
Это означает меньшее количество тестовых методов (что упрощает изменение логики тестов) и возможность быстро увидеть все входные данные и ожидаемые результаты для конкретного метода вместе.
В примере используется атрибут
[ClassData]
, который загружает тестовые данные из отдельного класса, реализующего IEnumerable<object[]>
.#dotnet #csharp #tip by Dave Callan
🛠️ Пример модульного теста C# с использованием паттерна Builder
💬 Кто использует паттерн Builder для настройки тестовых данных? В каких ситуациях оправданы дополнительные накладные расходы на обслуживание?
#dotnet #csharp #tip by Dave Callan
💬 Кто использует паттерн Builder для настройки тестовых данных? В каких ситуациях оправданы дополнительные накладные расходы на обслуживание?
#dotnet #csharp #tip by Dave Callan
Он был представлен в C# 11. Видимость созданного типа ограничена исходным файлом, в котором он объявлен.
Эта фича помогает избегать конфликтов имен при написании генераторов исходного кода.
💬 Как думаете, в каких кейсах его еще можно применить?
#dotnet #csharp #tip by Oleg Kyrylchuk
Please open Telegram to view this post
VIEW IN TELEGRAM
🔼 Spread element в C# 12: простой пример
Идея похожа на
💬 Уже пользовались?
#dotnet #csharp #tip by Dave Callan
Идея похожа на
...
( три точки) в JavaScript и используется для объединения коллекций.💬 Уже пользовались?
#dotnet #csharp #tip by Dave Callan
Начиная с версии 17.12 Preview 2, больше не нужно явно повторять значения, которые используются в разных окружениях.
#dotnet #csharp #tip by Dave Callan
Please open Telegram to view this post
VIEW IN TELEGRAM
Проблема заключалась в том, что обработчик исключений по умолчанию всегда устанавливал HTTP-код состояния ответа равным 500.
В ASP NET Core 9 представлена новая опция
StatusCodeSelector
, которая позволяет выбирать код состояния на основе исключения.👉 Подробнее
#dotnet #csharp #tip by Oleg Kyrylchuk
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
#dotnet #csharp #tip by Dave Callan
Please open Telegram to view this post
VIEW IN TELEGRAM
🥳 Новый формат .NET-решения .slnx теперь доступен в последней превью-версии Rider
Этот формат находится в режиме превью в Visual Studio, а теперь еще и в Rider. Кажется, с новым форматом улучшена читаемость и возможность слияния (mergeability). Выше — пример различий по сравнению с существующим форматом для простого решения.
#dotnet #csharp #tip by Dave Callan
Этот формат находится в режиме превью в Visual Studio, а теперь еще и в Rider. Кажется, с новым форматом улучшена читаемость и возможность слияния (mergeability). Выше — пример различий по сравнению с существующим форматом для простого решения.
#dotnet #csharp #tip by Dave Callan
По умолчанию он проверяет все правила и объединяет сообщения об ошибках. Более эффективно устанавливать
CascadeMode
либо на уровне класса, либо на уровне цепочки правил, особенно при использовании MustAsync
и асинхронных операций.#dotnet #csharp #tip by Saeed Esmaeelinejad
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как можно аннотировать основной конструктор атрибутом?
Ранее, если у записи/класса/структуры было несколько конструкторов, возникала проблема с десериализацией, так как необходимо было указать атрибут
Начиная с C# 12, можно использовать method attribute target для указания конструктора☝️
#dotnet #csharp #tip by Oleg Kyrylchuk
Ранее, если у записи/класса/структуры было несколько конструкторов, возникала проблема с десериализацией, так как необходимо было указать атрибут
JsonConstructor
в основном конструкторе.Начиная с C# 12, можно использовать method attribute target для указания конструктора☝️
#dotnet #csharp #tip by Oleg Kyrylchuk
🔒🔥 В .NET 9 появится новый тип
Отличный вариант для выделенного типа
#dotnet #tip by Steven Giesel
Lock()
Отличный вариант для выделенного типа
lock
, поскольку это дает нам способ более четко выразить намерение нашего кода. #dotnet #tip by Steven Giesel
💡 Parameter Object Pattern
Если метод принимает много связанных параметров, рассмотрите возможность группировки их в объект, чтобы упростить модификацию и сигнатуры.
Очень полезно, когда группа параметров часто используется повторно.
#dotnet #csharp #tip by Dave Callan
Если метод принимает много связанных параметров, рассмотрите возможность группировки их в объект, чтобы упростить модификацию и сигнатуры.
Очень полезно, когда группа параметров часто используется повторно.
#dotnet #csharp #tip by Dave Callan
🤔 Согласитесь, что глубоко вложенный код трудно читать?
В методах с большим количеством вложений можно использовать подход Early Return и Guard Clause, чтобы сделать код более удобным для чтения.
#dotnet #csharp #tip by Dave Callan
В методах с большим количеством вложений можно использовать подход Early Return и Guard Clause, чтобы сделать код более удобным для чтения.
#dotnet #csharp #tip by Dave Callan
👆 Кстати, в EF 9 представлен новый удобный способ заполнения базы данных начальными данными.
#efcore #dotnet #tip by Nabi Karampour
#efcore #dotnet #tip by Nabi Karampour
💡 Кстати,
Раньше приходилось перечислять каждый элемент complex типа в
#dotnet #efcore #tip by Oleg Kyrylchuk
ExecuteUpdate
поддерживает обновление complex типов в Entity Framework 9Раньше приходилось перечислять каждый элемент complex типа в
ExecuteUpdate
, а теперь он принимает complex тип, но вам все равно нужно указать каждый элемент.#dotnet #efcore #tip by Oleg Kyrylchuk
🚀 Сравнение производительности конкатенации строк в .NET 9
Есть и другие подходы, когда нам нужна ещё более высокая производительность, но из распространённых подходов, показанных ниже,
#dotnet #csharp #tip by Dave Callan
Есть и другие подходы, когда нам нужна ещё более высокая производительность, но из распространённых подходов, показанных ниже,
StringJoin
выигрывает. #dotnet #csharp #tip by Dave Callan
🚀Как ускорить LINQ: полезные трюки
1️⃣ Избегайте повторной обработки коллекций
Повторный вызов методов LINQ, таких как Where, приводит к повторному перебору коллекции.
✅ Решение: кэшируйте результаты, если они используются несколько раз:
2️⃣ Используйте ForEach вместо Select, если результат не нужен
Использование Select для выполнения действий без необходимости возвращать коллекцию увеличивает накладные расходы.
✅ Решение: используйте ForEach для простого выполнения действий:
3️⃣ Избегайте использования Count для проверки на пустоту
Count перебирает всю коллекцию, что замедляет выполнение.
✅ Решение: используйте Any() вместо Count():
4️⃣ Параллельное выполнение (PLINQ)
Обработка больших коллекций может быть медленной.
✅ Решение: используйте PLINQ для параллельного выполнения:
5️⃣ Проекционная оптимизация (Select)
Извлечение всех данных, когда требуется только несколько полей.
✅ Решение: Используйте Select для выборки только необходимых данных:
6️⃣ Фильтрация перед проекцией
Проекция больших объёмов данных перед фильтрацией замедляет запрос.
✅ Решение: сначала фильтруйте, затем проецируйте:
🐸 Библиотека шарписта
#tip
Повторный вызов методов LINQ, таких как Where, приводит к повторному перебору коллекции.
var filtered = myCollection.Where(x => x.Age > 30).ToList(); // Выполняется один раз
var count = filtered.Count;
var average = filtered.Average(x => x.Salary);
Использование Select для выполнения действий без необходимости возвращать коллекцию увеличивает накладные расходы.
myCollection.ForEach(x => Console.WriteLine(x.Name));
Count перебирает всю коллекцию, что замедляет выполнение.
if (myCollection.Any()) // Быстрее, чем myCollection.Count > 0
Обработка больших коллекций может быть медленной.
var result = myCollection.AsParallel()
.Where(x => x.IsActive)
.ToList();
Извлечение всех данных, когда требуется только несколько полей.
var names = myCollection.Select(x => x.Name).ToList();
Проекция больших объёмов данных перед фильтрацией замедляет запрос.
var result = myCollection.Where(x => x.Age > 30)
.Select(x => x.Name)
.ToList();
#tip
Please open Telegram to view this post
VIEW IN TELEGRAM
Метод FirstOrDefault в LINQ может стать источником путаницы. Он возвращает первый элемент последовательности или значение по умолчанию для типа, если элементов нет. Для ссылочных типов и Nullable<T> это null, а для значимых типов (например, int) — это их дефолтное значение (0, false и т.д.).
✏️ Например, вызов FirstOrDefault для пустого списка List<int> вернёт 0, что может быть неожиданно, если 0 имеет смысловое значение в вашем коде.
var numbers = new List<int> { };
var result = numbers.FirstOrDefault();
Console.WriteLine(result); // Вывод: 0
❗️Чтобы избежать ошибок, рекомендуется явно проверять коллекцию на пустоту перед вызовом метода или использовать DefaultIfEmpty, чтобы задать своё значение по умолчанию. Например:
var result = numbers.DefaultIfEmpty(null).FirstOrDefault();
Это гарантирует, что даже для пустой коллекции результат будет null, а не дефолтное значение типа. Такой подход делает код понятным и избавляет от скрытых проблем с обработкой "пустых" результатов.
#tip
Please open Telegram to view this post
VIEW IN TELEGRAM