9818
Авторский канал по разработке на C# и Unity. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Автор: @energy_it РКН: https://clck.ru/3SBaT3 Реклама на бирже: https://telega.in/c/csharp_ready
Локальная валидация и фильтрация в Minimal API с AddEndpointFilter!
В Minimal API удобно обрабатывать запросы в одной строчке. Но что, если нужно добавить проверку или логирование без лишней обвязки?
С .NET 8 можно использовать AddEndpointFilter — он добавляет поведение *только* к нужному эндпоинту.
Создаём минималку с фильтром на размер файла:
app.MapPost("/upload", UploadFile)
.AddEndpointFilter(async (context, next) =>
{
var file = context.GetArgument<IFormFile>(0);
if (file.Length > 5_000_000)
return Results.BadRequest("Файл слишком большой!");
return await next(context); // пропускаем дальше
});static IResult UploadFile(IFormFile file)
{
// сохраняем, обрабатываем и т.д.
return Results.Ok("Файл принят!");
}
👩💻 Разберем guid — структура .NET для представления глобальных уникальных идентификаторов!С её помощью можно гарантировать уникальность объектов в приложениях и распределённых системах, создавать и восстанавливать идентификаторы из строкового вида, сравнивать и упорядочивать их, а также проверять на отсутствие значения.
➡️ C# Ready | #шпора
📂 Напоминалка по Rate Limiting!
Например, Token Bucket отлично подходит для API с кратковременными burst-нагрузками, а Leaky Bucket помогает выравнивать поток запросов и защищать сервис от перегрузки.
На картинке — 5 популярных стратегий ограничения запросов, которые стоит знать каждому backend-разработчику.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
✍️ Godot + C# — основы разработки игр на C#!
Подробная документация по работе с C# в Godot 4: настройка проекта, структура скриптов, классы, сцены, сигналы и взаимодействие объектов внутри движка. Материал отлично подойдёт тем, кто хочет разрабатывать игры на Godot, используя привычный стек C# и .NET вместо GDScript. В документации много примеров кода и практических объяснений.
📌 Оставляю ссылочку: docs.godotengine.org
➡️ C# Ready | #ресурс
Почему ContainsKey() перед индексатором часто лишний?
Часто со словарём работают так:
if (users.ContainsKey(id))
{
var user = users[id];
}
ContainsKey(), второй — при обращении через индексатор.if (users.TryGetValue(id, out var user))
{
// используем user
}
TryGetValue() за один вызов проверяет ключ и возвращает значение.TryGetValue() обычно лучше, чем ContainsKey() + индексатор.
👩💻 Генерация фейковых пользователей с Bogus!
Небольшая консольная утилита, которая создаёт список тестовых пользователей: ID, полное имя, email, телефон и дату рождения — на основе библиотеки Bogus.
В этой задаче:
• Создаём консольный проект на C# и подключаем библиотеку Bogus.
• Генерируем список пользователей с реалистичными данными и локализацией.
• Выводим результат в удобном табличном формате.
📂 Шпаргалка по безопасности API!
Безопасный API — это не только HTTPS. Нужны authentication, authorization, input validation, rate limiting, audit logs, защита от replay-атак, корректная работа с токенами и ограничение доступа к чувствительным данным.
На картинке — основные практики, которые помогают защитить API от типовых уязвимостей и злоупотреблений.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Совет на 2027 год — переходите в ML.
Пока обычные разрабы конкурируют с ИИ-копилотами, ML-инженеры эти самые нейронки создают.
В эпоху нейростей это самые востребованые люди в мире программирования. Зарплаты мидлов начинаются от 250 000 ₽, а у сеньоров в BigTech доходят до 700 000 ₽.
А чтобы освоить его всего за 4 месяца без лишней суеты — изучите канал Марка Миргалеева.
Он помог 20+ ученикам найти работу от 250к в ML/NLP/AI-агентах
На канале вы найдёте:
— Всё про самые востребованные стеки(Python, ИИ-агенты, NLP) и почему математика — это не страшно, если учить только нужное.
— Как оформить резюме, чтобы оно пролетало через любые LLM-фильтры и ATS-системы прямо к тимлидам.
— Скрипты переговоров, которые помогли его ученикам прыгнуть с 0 до 360к всего за 8 месяцев.
Во времена острой нехватки ML-разработчиков, это лучшее время, чтобы перекатиться. Переходи и изучай: /channel/+TwxQ8W6MF6hhY2My
Почему пустой массив лучше брать через Array.Empty<T>()?
Когда нужно вернуть пустой массив, можно написать так:
return new User[0];
return Array.Empty<User>();
Почему TryParse() лучше, чем Parse() внутри try/catch?
Когда мы работаем с пользовательским вводом, строкой из файла, query-параметром или данными из внешней системы, невалидное значение — это не что-то неожиданное. Это обычный сценарий, который нужно аккуратно обработать.
Если использовать Parse() и ловить ошибку через try/catch, код выглядит так, будто произошла настоящая авария:
try
{
var age = int.Parse(input);
SaveAge(age);
}
catch
{
ShowError();
}
if (int.TryParse(input, out var age))
{
SaveAge(age);
}
else
{
ShowError();
}
TryParse() сразу показывает намерение:try/catch.
👩💻 Познакомимся с методами Convert — надёжным инструментом для приведения данных нужному типу!С их помощью можно легко преобразовывать строки и числа в нужные типы, такие как int, double, bool, а также выполнять универсальное преобразование с помощью ChangeType и работать с Base64 для сериализации и передачи данных.
➡️ C# Ready | #шпора
Создаём копию объекта с изменёнными данными!
Иногда нужно взять существующий объект и изменить в нём только одно-два значения.
Например, у нас есть record с данными пользователя:
record User(string Name, int Age);
User user = new User("Анна", 25);
Console.WriteLine(user);User { Name = Анна, Age = 25 }User updatedUser = new User(user.Name, 26);
Console.WriteLine(updatedUser);
record можно использовать выражение with:User updatedUser = user with { Age = 26 };
Console.WriteLine(updatedUser);with создаёт копию объекта и меняет только указанные свойства.User { Name = Анна, Age = 26 }with удобно использовать, когда нужно аккуратно обновлять immutable-объекты без ручного копирования всех данных
☕️ DotNetCurry — отличный источник знаний для .NET-разработчиков!
Он собрал в себе подробные статьи, пошаговые руководства и примеры кода по C#, ASP․NET, Blazor, Entity Framework и другим технологиям экосистемы Microsoft.
📌 Оставляю ссылочку: dotnetcurry.com
➡️ C# Ready | #ресурс
📝 Напоминалка по REST API!
Например, GET используют для получения данных, POST — для создания, PUT/PATCH — для обновления, а DELETE — для удаления ресурса.
На шпаргалке — принципы REST, HTTP-методы, версионирование, пагинация, фильтрация и best practices для API.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Отслеживаем изменения в папке через FileSystemWatcher — мгновенный отклик без опроса!
Иногда нужно сразу реагировать, когда в каталоге появляется новый файл отчёта или изменяется конфигурация. Вместо бесконечных таймеров используем встроенный наблюдатель файловой системы.
Сначала задаём путь и настраиваем watcher: реагируем на создание и изменение только .txt-файлов, подписываемся на события Created и Changed:
using System.IO;
string path = @"C:\Watched";
using var watcher = new FileSystemWatcher(path, "*.txt")
{
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
IncludeSubdirectories = false,
// или true — если нужны подпапки
EnableRaisingEvents = true
// запускаем слежение
};
watcher.Created += OnChanged;
watcher.Changed += OnChanged;
static void OnChanged(object sender, FileSystemEventArgs e)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {e.ChangeType}: {e.FullPath}");
}
Console.WriteLine($"👀 Слежение за {path} запущено. Нажмите Enter для выхода…");
Console.ReadLine();FileSystemWatcher избавляет от циклов опроса: оперативно, без лишних ресурсов и под любые типы файлов.
📂 Шпаргалка по LINQ для .NET разработчика!
Например, Where() фильтрует коллекции, Select() преобразует данные, а GroupBy() помогает быстро группировать элементы по ключу.
На картинке — основные LINQ-методы, разбитые по категориям: фильтрация, сортировка, агрегация, группировка, работа с последовательностями и другое.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Guard: создаём свои проверки аргументов
Иногда в метод приходит значение, которое обязательно должно быть заполнено: email, имя пользователя, путь к файлу или строка подключения.
Часто такие проверки пишут прямо внутри метода:
void CreateUser(string email)
{
if (string.IsNullOrWhiteSpace(email))
throw new ArgumentException("Email is empty");
Console.WriteLine($"User created: {email}");
}
public static class Guard
{
public static string NotEmpty(string value, string name)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException($"{name} is empty");
return value;
}
}
void CreateUser(string email)
{
email = Guard.NotEmpty(email, nameof(email));
Console.WriteLine($"User created: {email}");
}
NotEmpty сразу делает две вещи: проверяет значение и возвращает его обратно, если всё нормально.if ты собираешь проверки в одном месте.public static class GuardExtensions
{
public static string NotEmpty(this string value, string name)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException($"{name} is empty");
return value;
}
}
void CreateUser(string email)
{
email = email.NotEmpty(nameof(email));
Console.WriteLine($"User created: {email}");
}
Почему IEnumerable лучше не перечислять несколько раз?IEnumerable<T> выглядит как обычная коллекция, но это может быть не список.
Это может быть LINQ-запрос, чтение из файла, генератор или результат из базы.
Например:
if (orders.Count() > 0)
{
foreach (var order in orders)
Process(order);
}
Count() может пройти всю последовательность.foreach пройдёт её ещё раз.var orderList = orders.ToList();
foreach.
👍Камера и AI прямо в MAUI!
В этой статье:• Получаем кадры с камеры без лишних задержек.• Запускаем распознавание лиц через MediaPipe Tasks.• Рисуем оверлеи поверх живого изображения.
🔊 Продолжай читать на habr!
😎 Lucidchart — платформа для построения диаграмм, моделирования процессов и визуализации архитектуры!
Позволяет формализовать и наглядно представить сложные системы: от backend-архитектуры и UML-диаграмм до бизнес-процессов и пользовательских сценариев. Поддерживает совместную работу, интеграции с корпоративными сервисами и автоматизацию создания схем. Подходит для проектирования, технической документации и коммуникации внутри команд.
📌 Оставляю ссылочку: lucidchart.com
➡️ C# Ready | #ресурс
Требуются парни и девушки в возрасте 19–40 лет, желающие работать в сфере IT.
Опыт в программировании не нужен.
Завтра запускаем бесплатный онлайн-интенсив по Frontend-разработке, где будем показывать, как разрабатывать сайты и веб-приложения в 2026 году без навыков в программировании.
За 7 дней обучения ты:
1. Создашь полноценный веб-сайт на HTML и CSS;
2. Оживишь страницу с помощью JavaScript;
3. Используешь фронтенд-фреймворк Angular;
4. Подключишь Backend и загрузишь сайт на хостинг;
5. Получишь советы по доработке своего проекта;
6. Узнаешь сколько можно зарабатывать и как работать;
7. Поймёшь, как получать заказы на разработку в эпоху нейронок.
А главное, ты увидишь, что разрабатывать сайты и приложения не так сложно, как кажется. И поймёшь, как тебе развиваться в этой профессии, чтобы уже через месяц зарабатывать от 1000$ на вёрстке сайтов.
👉 Проскочить на интенсив бесплатно
🔥 С нас обучение, практика и помощь с выходом на фриланс.
scoped в C#: как не дать ссылке “убежать” наружу!
Иногда при работе со Span<T>, ref и памятью важно не только избежать лишних аллокаций, но и не вернуть наружу ссылку на данные, которые скоро перестанут существовать.
Например, такой код может выглядеть безобидно:
static ReadOnlySpan<char> GetPrefix(ReadOnlySpan<char> text)
{
return text.Slice(0, 3);
}
Span<T>, stackalloc и ref-параметрами.scoped:static void PrintPrefix(scoped ReadOnlySpan<char> text)
{
var prefix = text.Slice(0, 3);
Console.WriteLine(prefix.ToString());
}
scoped говорит компилятору: этот параметр можно использовать внутри метода, но нельзя сохранить так, чтобы ссылка пережила текущий вызов.stackalloc:Span<int> numbers = stackalloc int[] { 1, 2, 3, 4, 5 };
Print(numbers);
static void Print(scoped Span<int> values)
{
foreach (var value in values)
Console.WriteLine(value);
}scoped помогает не дать ссылке на них случайно “утечь” наружу.scoped не делает код быстрее сам по себе. Его задача другая — сделать работу с памятью безопаснее и понятнее для компилятора.
❤️ Awesome .NET Core — огромная база ресурсов по .NET и ASPNET Core!
Здесь собрано практически всё для .NET-разработчика: библиотеки, шаблоны, инструменты, ORM, статьи, архитектурные решения и полезные сервисы для backend-разработки на .NET Core. Особенно полезно тем, кто работает с ASPNET Core, микросервисами, Docker и современным backend-стеком. Можно быстро найти готовые решения, нужные инструменты и сильно ускорить разработку.
Оставляю ссылочку: GitHub 📱
🧐 Разбираем типичные варианты архитектурных ошибок!
Нашёл полезный разбор типичных ошибок в C#-проектах: перегруженные классы, смешение слоёв и слабая декомпозиция.
В статье:• почему проект быстро становится неуправляемым• как смешение логики, API и базы усложняет поддержку• зачем разделять ответственность между слоями
🔊 Продолжай читать на Habr!
😎 Полезный разбор типичных ошибок в C#-проектах: перегруженные классы, смешение слоёв и слабая декомпозиция!
В этой статье:• почему проект быстро становится неуправляемым
• как смешение логики, API и базы усложняет поддержку
• зачем разделять ответственность между слоями
🔊 Продолжай читать на Habr!
❤️ Free Programming Books — огромная коллекция бесплатных книг по программированию!
В этом репозитории собраны десятки книг по разным языкам и направлениям, таким как С# и многое другое. Всё разложено по категориям, поэтому можно быстро найти нужную тему. Здесь есть как базовые учебники по синтаксису и указателям, так и более серьёзные материалы по памяти, низкоуровневой работе и системному программированию.
Оставляю ссылочку: GitHub 📱
📂 Напоминалка по UML Class Diagrams!
Например, Association показывает связь между классами, Inheritance — наследование, а Composition — ситуацию, когда один объект является частью другого.
На картинке — основные элементы UML-диаграмм классов: классы, методы, атрибуты, интерфейсы и типы связей.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
👩💻 Убираем хрупкие строки с помощью nameof!nameof помогает брать имя свойства, метода или переменной прямо из кода, а не писать его руками обычной строкой.
Что важно знать:
• nameof возвращает имя элемента в виде строки
• При переименовании IDE обновит ссылку, а не оставит старый текст
• Особенно полезен в логах, ошибках, валидации и отладке
Получаем имя переменной с nameof безопасно!
Иногда нужно передать имя переменной, свойства или метода в виде строки.
Например, можно написать так:
string userName = "Анна";
Console.WriteLine("userName");
"userName" никак не связана с самой переменной.nameof:string userName = "Анна";
Console.WriteLine(nameof(userName));
nameof возвращает имя переменной, свойства, класса или метода в виде строки.userName
void PrintName(string name)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
Console.WriteLine(name);
}
name IDE обновит и использование внутри nameof.nameof помогает избежать ошибок в строках и делает код безопаснее при рефакторинге
😎 Иногда вложенные циклы в C# превращаются в маленький лабиринт!
Нашёл свежий разбор про labeled break и continue в C# 15 — фичу, которая может сделать выход из вложенных циклов чуть понятнее, но при неправильном использовании легко ухудшит читаемость.
В статье:• как обычно выходят из нескольких вложенных циклов• что предлагают labeled break и continue• почему новая возможность не отменяет нормальный рефакторинг кода
🔊 Продолжай читать на Habr!