Библиотека шарписта | C#, F#, .NET, ASP.NET
23.3K subscribers
2.1K photos
32 videos
85 files
4.27K links
Все самое полезное для C#-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Download Telegram
🛠️ Пример параметризованного теста xUnit

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

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

В примере используется атрибут [ClassData], который загружает тестовые данные из отдельного класса, реализующего IEnumerable<object[]>.

#dotnet #csharp #tip by Dave Callan
🛠️ Пример модульного теста C# с использованием паттерна Builder

💬 Кто использует паттерн Builder для настройки тестовых данных? В каких ситуациях оправданы дополнительные накладные расходы на обслуживание?

#dotnet #csharp #tip by Dave Callan
💡Модификатор доступа к файлу в C#

Он был представлен в C# 11. Видимость созданного типа ограничена исходным файлом, в котором он объявлен.

Эта фича помогает избегать конфликтов имен при написании генераторов исходного кода.

💬 Как думаете, в каких кейсах его еще можно применить?

#dotnet #csharp #tip by Oleg Kyrylchuk
Please open Telegram to view this post
VIEW IN TELEGRAM
🔼 Spread element в C# 12: простой пример

Идея похожа на ... ( три точки) в JavaScript и используется для объединения коллекций.

💬 Уже пользовались?

#dotnet #csharp #tip by Dave Callan
👩‍💻 «Шарьте» значения между окружениями с помощью http-файлов в Visual Studio

Начиная с версии 17.12 Preview 2, больше не нужно явно повторять значения, которые используются в разных окружениях.

#dotnet #csharp #tip by Dave Callan
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 В ASP NET Core 8 появился IExceptionHandler

Проблема заключалась в том, что обработчик исключений по умолчанию всегда устанавливал 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
👩‍💻 Совместное использование настроек сборки в нескольких .NET-проектах: на заметку C#-разработчику

#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
🤔FluentValidation: прекратите проверять правила при первой ошибке

По умолчанию он проверяет все правила и объединяет сообщения об ошибках. Более эффективно устанавливать CascadeMode либо на уровне класса, либо на уровне цепочки правил, особенно при использовании MustAsync и асинхронных операций.

#dotnet #csharp #tip by Saeed Esmaeelinejad
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как можно аннотировать основной конструктор атрибутом?

Ранее, если у записи/класса/структуры было несколько конструкторов, возникала проблема с десериализацией, так как необходимо было указать атрибут JsonConstructor в основном конструкторе.

Начиная с C# 12, можно использовать method attribute target для указания конструктора☝️

#dotnet #csharp #tip by Oleg Kyrylchuk
🔒🔥 В .NET 9 появится новый тип Lock()

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

#dotnet #tip by Steven Giesel
💡 Parameter Object Pattern

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

Очень полезно, когда группа параметров часто используется повторно.

#dotnet #csharp #tip by Dave Callan
🤔 Согласитесь, что глубоко вложенный код трудно читать?

В методах с большим количеством вложений можно использовать подход Early Return и Guard Clause, чтобы сделать код более удобным для чтения.

#dotnet #csharp #tip by Dave Callan
👆 Кстати, в EF 9 представлен новый удобный способ заполнения базы данных начальными данными.

#efcore #dotnet #tip by Nabi Karampour
💡 BenchmarkDotNet в действии: простой пример для C#-разработчика

#dotnet #tip by Dave Callan
💡 Кстати, ExecuteUpdate поддерживает обновление complex типов в Entity Framework 9

Раньше приходилось перечислять каждый элемент complex типа в ExecuteUpdate, а теперь он принимает complex тип, но вам все равно нужно указать каждый элемент.

#dotnet #efcore #tip by Oleg Kyrylchuk
🚀 Сравнение производительности конкатенации строк в .NET 9

Есть и другие подходы, когда нам нужна ещё более высокая производительность, но из распространённых подходов, показанных ниже, StringJoin выигрывает.

#dotnet #csharp #tip by Dave Callan
Сохраняйте себе #tip, чтобы не забыть!
🚀Как ускорить LINQ: полезные трюки

1️⃣Избегайте повторной обработки коллекций
Повторный вызов методов LINQ, таких как Where, приводит к повторному перебору коллекции.
Решение: кэшируйте результаты, если они используются несколько раз:
var filtered = myCollection.Where(x => x.Age > 30).ToList(); // Выполняется один раз
var count = filtered.Count;
var average = filtered.Average(x => x.Salary);


2️⃣Используйте ForEach вместо Select, если результат не нужен
Использование Select для выполнения действий без необходимости возвращать коллекцию увеличивает накладные расходы.
Решение: используйте ForEach для простого выполнения действий:
myCollection.ForEach(x => Console.WriteLine(x.Name));


3️⃣Избегайте использования Count для проверки на пустоту
Count перебирает всю коллекцию, что замедляет выполнение.
Решение: используйте Any() вместо Count():
if (myCollection.Any()) // Быстрее, чем myCollection.Count > 0


4️⃣Параллельное выполнение (PLINQ)

Обработка больших коллекций может быть медленной.
Решение: используйте PLINQ для параллельного выполнения:
var result = myCollection.AsParallel()
.Where(x => x.IsActive)
.ToList();


5️⃣Проекционная оптимизация (Select)
Извлечение всех данных, когда требуется только несколько полей.
Решение: Используйте Select для выборки только необходимых данных:
var names = myCollection.Select(x => x.Name).ToList();


6️⃣Фильтрация перед проекцией
Проекция больших объёмов данных перед фильтрацией замедляет запрос.
Решение: сначала фильтруйте, затем проецируйте:
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

Метод 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