Как не писать if (x == null) throw ... вручную?
В C# мы постоянно защищаемся от
Это работает, но:
• код раздувается от однотипных проверок,
• легко забыть
• “полезная” логика тонет в бойлерплейте.
В современных версиях .NET есть короткий и безопасный вариант:
Он делает ровно то же самое — бросает
🔥 Итог: вместо ручного
➡️ C# Ready | #совет
В C# мы постоянно защищаемся от
null: в публичных методах, сервисах, хендлерах, контроллерах. И почти в каждом месте повторяется один и тот же шаблон:if (options == null)
throw new ArgumentNullException(nameof(options));
Это работает, но:
• код раздувается от однотипных проверок,
• легко забыть
nameof(...) или написать не то имя,• “полезная” логика тонет в бойлерплейте.
В современных версиях .NET есть короткий и безопасный вариант:
ArgumentNullException.ThrowIfNull(options);
Он делает ровно то же самое — бросает
ArgumentNullException, если аргумент null, — но запись становится в разы чище.if (...) throw ... используй ArgumentNullException.ThrowIfNull(x) — меньше шума, меньше копипасты, проще читать метод с первого взгляда.Please open Telegram to view this post
VIEW IN TELEGRAM
1👍14🤝6🔥3❤1
В этой статье:
• Разобраться, чем incremental отличается от классических генераторов• Увидеть, как собирается пайплайн: провайдеры, трансформации• Понять практические кейсы: генерация boilerplate, DSL-подходы🔊 Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤5🔥4😁1
Обрабатываем ошибки с try-catch-finally!
Сейчас научимся ловить ошибки во время выполнения программы с помощью конструкции
Подключим нужные библиотеки — всё уже есть в стандартной библиотеке:
Допустим, мы хотим преобразовать строку в число. Если строка — не число, программа «упадёт»:
Чтобы программа не завершалась с ошибкой, обернём этот код в
Если строка не может быть преобразована в число, будет выброшено исключение типа
И наконец, добавим блок
🔥 Без
➡️ C# Ready | #практика
Сейчас научимся ловить ошибки во время выполнения программы с помощью конструкции
try-catch. Это особенно полезно, когда пользователь может ввести некорректные данные — например, буквы вместо чисел.Подключим нужные библиотеки — всё уже есть в стандартной библиотеке:
using System;
Допустим, мы хотим преобразовать строку в число. Если строка — не число, программа «упадёт»:
string input = "abc";
int number = Convert.ToInt32(input); // тут возникнет ошибка
Чтобы программа не завершалась с ошибкой, обернём этот код в
try-catch. Если произойдёт исключение, оно будет поймано и обработано:try {
string input = "abc";
int number = Convert.ToInt32(input);
Console.WriteLine($"Число: {number}");
}Если строка не может быть преобразована в число, будет выброшено исключение типа
FormatException. catch (FormatException) {
Console.WriteLine("Ошибка: введена нечисловая строка.");
}И наконец, добавим блок
finally. Он выполняется всегда — даже если произошла ошибка. finally {
Console.WriteLine("Завершено выполнение блока.");
}🔥 Без
try-catch программа завершилась бы аварийно. А с обработкой исключений — работает стабильно, даже при ошибочном вводе.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤7🔥4😁1
Почему async void почти всегда ошибка?
При работе с асинхронным кодом в C# многие по привычке пишут
Разберёмся, в чём проблема и как правильно писать асинхронные методы.
Создадим метод с
Вызовем его:
При запуске приложение завершится с ошибкой, и мы не сможем поймать исключение через
Теперь перепишем метод правильно — с
Вызовем его с обработкой ошибок:
Результат в консоли:
🔥
➡️ C# Ready | #практика
При работе с асинхронным кодом в C# многие по привычке пишут
async void, не задумываясь о последствиях. На первый взгляд всё работает, но такие методы могут привести к трудноуловимым багам.Разберёмся, в чём проблема и как правильно писать асинхронные методы.
Создадим метод с
async void:async void DoWorkAsync()
{
await Task.Delay(1000);
throw new Exception("Ошибка внутри async void");
}
Вызовем его:
DoWorkAsync();
Console.WriteLine("Метод вызван");
При запуске приложение завершится с ошибкой, и мы не сможем поймать исключение через
try/catch.Теперь перепишем метод правильно — с
async Task:async Task DoWorkAsync()
{
await Task.Delay(1000);
throw new Exception("Ошибка внутри async Task");
}
Вызовем его с обработкой ошибок:
try
{
await DoWorkAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Результат в консоли:
Ошибка внутри async Task
async void нельзя await и в нём невозможно корректно обработать исключения. Используй async Task, а async void оставляй только для обработчиков событий.Please open Telegram to view this post
VIEW IN TELEGRAM
❤12🔥7👍5
This media is not supported in your browser
VIEW IN TELEGRAM
Вводишь любую команду в терминале, и он по частям объясняет, что делает каждая часть. Не просто man-ка, а понятный синтакс-анализ.
Особенно кайф для тех, кто работает в
Linux/DevOps/CI среде и хочет разбираться, а не наугад копипастить из StackOverflow.Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥8❤5
ArrayPool особенно хорош в “горячем” коде, где буферы создаются сотни/тысячи раз: сериализация, парсинг, сетевые пакеты, кодирование строк.В что важно знать:
• Rent() может вернуть массив больше запрошенного;
• Return() — всегда (лучше через try/finally);
• После Return() массив использовать нельзя; для секретов — clearArray: true
Если у тебя много временных
byte[]/char[] — ArrayPool<T> почти всегда даёт профит, но требует дисциплины.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥23❤7👍5
На картинке — компактный
quick reference по базовым вещам в C#: примитивные типы и их размеры, работа с массивами, частые операции со строками, форматирование чисел и дат, основы регулярных выраженийСохрани, чтобы под рукой была выжимка для кодинга и ревью.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍6🔥5
Как не писать Any() перед First()?
Частая привычка — сначала проверить коллекцию, а потом взять первый элемент:
Проблема в том, что это:
• добавляет лишний шум в код,
• нередко делает двойной проход по источнику (особенно если это
• усложняет чтение: полезная логика прячется за проверками.
Вместо связки
Если тебе нужно “взять элемент или вернуть дефолт”, это читается как правило и не заставляет выполнять одну и ту же работу дважды.
🔥 Итог: не проверяй
➡️ C# Ready | #совет
Частая привычка — сначала проверить коллекцию, а потом взять первый элемент:
if (items != null && items.Any())
{
var first = items.First();
// ...
}
Проблема в том, что это:
• добавляет лишний шум в код,
• нередко делает двойной проход по источнику (особенно если это
IEnumerable, LINQ-запрос, поток данных),• усложняет чтение: полезная логика прячется за проверками.
Вместо связки
Any() + First() обычно достаточно сразу использовать безопасный вариант:var first = items.FirstOrDefault();
if (first is null) return; // или другой fallback
Если тебе нужно “взять элемент или вернуть дефолт”, это читается как правило и не заставляет выполнять одну и ту же работу дважды.
Any() перед First() — чаще бери FirstOrDefault() (или SingleOrDefault() для “должен быть один”) и обработай null/default один раз в понятном месте.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍10❤4
В этой статье:
• Поймёшь, зачем генерация конструкторов снижает бойлерплейт и ошибки• Увидишь, как атрибуты описывают зависимости и правила инъекции• Разберёшь подключение генератора, ограничения, нюансы и реальные кейсы🔊 Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4🔥2
Lazy<T>: создаём объект только тогда, когда он реально нужен!
Иногда объект создаётся «на всякий случай», хотя по факту используется редко (например, тяжёлый сервис, настройки, конфиг, загрузка файла). В итоге мы тратим время и ресурсы при старте приложения зря.
Допустим, у нас есть «тяжёлый» объект, который долго создаётся:
Теперь создадим
А теперь впервые обратимся к объекту через
Возможный вывод в консоли:
🔥
➡️ C# Ready | #практика
Иногда объект создаётся «на всякий случай», хотя по факту используется редко (например, тяжёлый сервис, настройки, конфиг, загрузка файла). В итоге мы тратим время и ресурсы при старте приложения зря.
Lazy<T> решает это просто: объект создаётся только при первом обращении к нему.Допустим, у нас есть «тяжёлый» объект, который долго создаётся:
class HeavyService
{
public HeavyService()
{
Console.WriteLine("Создаём HeavyService (дорого)...");
// здесь могла бы быть долгая инициализация
}
public string GetData() => "Данные получены";
}
Теперь создадим
Lazy<HeavyService>. Обрати внимание: конструктор HeavyService не вызывается сразу:var lazyService = new Lazy<HeavyService>(() => new HeavyService());
Console.WriteLine("Lazy создан, но сервис ещё не создан");
А теперь впервые обратимся к объекту через
.Value — вот тут он и создастся:Console.WriteLine(lazyService.Value.GetData());
Возможный вывод в консоли:
Lazy создан, но сервис ещё не создан
Создаём HeavyService (дорого)...
Данные получены
Lazy<T> помогает ускорить старт приложения и не создавать тяжёлые объекты заранее — они появятся только если реально понадобятся.Please open Telegram to view this post
VIEW IN TELEGRAM
👍22❤9🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Здесь собраны десятки CLI-инструментов, полезные bash/zsh-скрипты, практичные сниппеты и лайфхаки, которые ускоряют работу. Отличный набор для автоматизации, оптимизации и прокачки навыков работы с командной строкой.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤9🤝7👍1
❤8👍7🔥4
На картинке — компактная карта команд Git, где всё разложено по логике работы: от создания репозитория и просмотра истории до внесения изменений, откатов, обновления из удалённого репо, работы с ветками и публикации результата.
Сохрани, чтобы быстро освежить в памяти нужный шаг, когда Git внезапно “начинает жить своей жизнью”
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥7❤5
Span<T> на пальцах — быстрый доступ к данным без лишних аллокаций!
Часто мы режем строки, копируем массивы, делаем
Допустим, у нас есть строка, и мы хотим достать из неё только число:
Обычно делают так (и это создаёт новую строку):
Теперь сделаем то же самое через
Результат:
🔥
➡️ C# Ready | #практика
Часто мы режем строки, копируем массивы, делаем
Substring и создаём новые объекты там, где можно обойтись без копирования. Это даёт лишние аллокации и нагрузку на GC.Span<T> позволяет работать с участком памяти (частью массива/строки) как с “окном”, не создавая новые объекты.Допустим, у нас есть строка, и мы хотим достать из неё только число:
string text = "User:42;Role:Admin";
Обычно делают так (и это создаёт новую строку):
string idText = text.Substring(5, 2);
int id = int.Parse(idText);
Console.WriteLine(id);
Теперь сделаем то же самое через
Span<char> — без Substring:ReadOnlySpan<char> span = text.AsSpan();
// берём "42" как срез
ReadOnlySpan<char> idSpan = span.Slice(5, 2);
// парсим напрямую из Span
int userId = int.Parse(idSpan);
Console.WriteLine(userId);
Результат:
42
Span<T> (и ReadOnlySpan<T>) позволяет брать срезы без копирования данных. Это особенно полезно в горячих участках кода: парсинг, обработка строк, сетевые протоколы, высоконагруженные сервисы.Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍7🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Если тебе сложно понять алгоритмы по учебникам — этот ресурс решает проблему. Автор объясняет графы, геометрию, деревья, меши из геймдева через понятные визуализации и интерактивы. Сложные идеи здесь раскладываются на простые шаги.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤8🔥6