Как не писать 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
Как получить уникальные значения без ручных проверок?
Часто нужно убрать дубликаты: имена пользователей, id, теги.
Иногда для этого пишут такую конструкцию:
Это работает, но в
Гораздо проще (и читабельнее) использовать готовые инструменты:
Для LINQ — Distinct()
Она сама уберёт дубли и вернёт последовательность уникальных значений:
Для максимальной скорости — `HashSet`
🔥 Итог: когда нужны уникальные значения — начинай с
➡️ C# Ready | #совет
Часто нужно убрать дубликаты: имена пользователей, id, теги.
Иногда для этого пишут такую конструкцию:
if (!list.Contains(x))
list.Add(x);
Это работает, но в
Contains список просматривается каждый раз — чем больше данных, тем медленнее. Да и выглядит это как “велосипед”.Гораздо проще (и читабельнее) использовать готовые инструменты:
Для LINQ — Distinct()
Она сама уберёт дубли и вернёт последовательность уникальных значений:
var unique = names.Distinct().ToList();
Для максимальной скорости — `HashSet`
HashSet<T> из коробки хранит только уникальные элементы, без повторов:var set = new HashSet<string>(names);
Distinct() или HashSet. Меньше ручных проверок, меньше кода, и алгоритм сразу читается как правило: *“здесь храним только уникальные элементы”*.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍9❤8
This media is not supported in your browser
VIEW IN TELEGRAM
Если обычные видеоуроки не заходят и хочется больше практики — Scrimba решает эту задачу. Здесь обучение построено так, что ты не просто смотришь объяснение, а сразу работаешь с кодом прямо в уроке: меняешь примеры, запускаешь и смотришь результат. На платформе есть множество языков и технологий.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤8🔥7
Поставлю себе цель: набрать более 20 тысяч подписчиков. Желаю каждому выполнить планы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥27❤12👍9
Как сравнивать строки без сюрпризов от локали?
Частая привычка — приводить строки к одному регистру и сравнивать:
Но это:
• делает лишние аллокации (создаёт новые строки),
• может зависеть от текущей культуры (локали) и давать неожиданные результаты.
Правильнее — сравнивать строки с явным режимом:
А если нужно “по-человечески” (для отображения пользователю) — тогда уместнее
🔥 Итог: меньше аллокаций, предсказуемое сравнение и код, который сразу говорит: “сравниваем без учёта регистра — и точка”.
➡️ C# Ready | #совет
Частая привычка — приводить строки к одному регистру и сравнивать:
a.ToLower() == b.ToLower()
Но это:
• делает лишние аллокации (создаёт новые строки),
• может зависеть от текущей культуры (локали) и давать неожиданные результаты.
Правильнее — сравнивать строки с явным режимом:
string.Equals(a, b, StringComparison.OrdinalIgnoreCase)
StringComparison.OrdinalIgnoreCase — самый безопасный вариант для технических строк: ключей, логинов, кодов, файлов, заголовков, команд.А если нужно “по-человечески” (для отображения пользователю) — тогда уместнее
CurrentCultureIgnoreCase, но это уже другое правило.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17❤11👍7
Как перестать писать ContainsKey + индексатор (и не искать ключ дважды)?
Частая ошибка при работе с
• делает два поиска по словарю,
• легко превращается в баг, если кто-то забудет проверку и оставит просто
Вместо этого используй
А если тебе нужно “дай значение или дефолт” — ещё проще:
🔥 Итог: меньше лишних проверок и двойных обращений к словарю, ниже шанс словить
➡️ C# Ready | #совет
Частая ошибка при работе с
Dictionary — сначала проверить ContainsKey, а потом взять значение через dict[key]. Это:• делает два поиска по словарю,
• легко превращается в баг, если кто-то забудет проверку и оставит просто
dict[key].Вместо этого используй
TryGetValue — он и проверяет наличие ключа, и достаёт значение за один проход:var count = dict.TryGetValue(key, out var value) ? value : 0;
А если тебе нужно “дай значение или дефолт” — ещё проще:
var count = dict.GetValueOrDefault(key, 0);
KeyNotFoundException, а код читается как правило: “если ключа нет — верни 0”.Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥6❤4
required свойства: компилятор заставит заполнить поля!
Часто в коде создают объекты, забывая заполнить важные свойства. Ошибка всплывает поздно — где-то в рантайме, когда поле внезапно
Обычно это выглядит так:
И получаем проблему уже при использовании:
В C# 11 можно пометить обязательные свойства как
🔥
➡️ C# Ready | #практика
Часто в коде создают объекты, забывая заполнить важные свойства. Ошибка всплывает поздно — где-то в рантайме, когда поле внезапно
null.Обычно это выглядит так:
class UserDto
{
public string Name { get; set; }
public string Email { get; set; }
}
var user = new UserDto
{
Name = "Анна"
// Email забыли…
};
И получаем проблему уже при использовании:
Console.WriteLine(user.Email.Length); // NullReferenceException
В C# 11 можно пометить обязательные свойства как
required — и компилятор не даст создать объект без них:class UserDto
{
public required string Name { get; init; }
public required string Email { get; init; }
}
var user = new UserDto
{
Name = "Анна",
Email = "anna@mail.com"
};
required + init = безопасная инициализация: меньше сюрпризов в рантайме, больше контроля на этапе компиляции.Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤6🔥4
На картинке — аккуратная “C# Cheat Sheet”, которая помогает быстро вспомнить основы языка: как писать комментарии, работать с перечислениями
enum, использовать циклы for, while и foreach, объявлять и использовать пространства имён, создавать объекты и вызывать методы, а также понимать, как работают делегаты и события в C#.Сохрани, чтобы код на C# стал проще и понятнее
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🔥6👍5👎1
В этой шпаргалке — практичный разбор, чем отличаются эти два подхода в async-коде: как быстро вернуть готовый результат, где ValueTask экономит аллокации, почему иногда лучше конвертировать в Task и как не поймать неожиданные проблемы с повторным ожиданием.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20❤5👍5