C# 1001 notes – Telegram
C# 1001 notes
6.53K subscribers
381 photos
10 videos
2 files
338 links
Регулярные короткие заметки по C# и .NET.

Просто о сложном для каждого.

admin - @haarrp
Download Telegram
🚀 .NET 10 - реально мощный релиз. Вот что важно знать 👇

.NET 10 и C# 14 вышли 11 ноября 2025 года.
Это LTS-версия - поддержку будут выпускать до ноября 2028 года,
поэтому её можно спокойно брать для продакшна.

🔥 Главное

C# 14
Новый синтаксис и возможности языка:
• Extension Members — расширения прямо в типах
• Null-Conditional Assignment - безопасные присваивания
field keyword — точный контроль над авто-свойствами
• Модификаторы у параметров лямбд
• Частичные конструкторы и события

File-Based Apps

Теперь можно просто создать один .cs файл и запускать приложение -
без .sln, без .csproj. Быстро, просто, удобно.

ASP.NET Core
• Валидация в Minimal APIs
• JSON Patch
• SSE (Server-Sent Events)
• Поддержка OpenAPI 3.1

EF Core
• Complex Types можно делать optional
• JSON и struct внутри Complex Types
• LeftJoin / RightJoin
• Named Query Filters
• ExecuteUpdate работает с JSON-колонками
• В ExecuteUpdate теперь можно использовать обычные лямбды


Полный гайд здесь:
https://antondevtips.com/blog/new-features-in-dotnet-10-and-csharp-14/?utm_source=twitter&utm_medium=social&utm_campaign=04-12-2025
Крутая статья - «Building an Event Queue in ASP.NET Core» от Deepumi.

🔹 Она показывает, как правильно построить очередь событий внутри ASP.NET Core-приложения:
• использовать встроенные механизмы (middleware / DI)
• распределять события между обработчиками
• обрабатывать события асинхронно и надёжно

🔹 Такая архитектура помогает:
• реализовать decoupled компоненты, которые не знают друг о друге
• централизовать событие-поток (логика, оповещения, триггеры и т.п.)
• легче масштабировать и тестировать код

Если работаешь с ASP.NET Core и хочешь сделать систему событий - стоит заглянуть.

Подробнее: deepumi.com/blog/building-an-event-queue-in-aspnet-core.html
🚦 Feature Flags в .NET - как управлять релизами без redeploy

Feature flags (фиче-флаги) позволяют включать и выключать функциональность на лету, без повторного деплоя и риска для продакшена.

Идея простая:
код задеплоен → поведение управляется конфигурацией.

Что это даёт на практике:
— Постепенные релизы
Можно включить новую фичу сначала для 1%, 10% или конкретной группы пользователей.
— Быстрый rollback
Если что-то пошло не так — просто выключаете флаг. Без откатов и срочных хотфиксов.
— A/B тесты
Разные пользователи получают разное поведение одного и того же кода.
— Targeting пользователей

Фичи можно включать:
• по user id
• по роли
• по региону
• по environment (dev / staging / prod)

— Меньше фиче-веток
Код живёт в main, а не за флагами в git.

В .NET обычно используют:
- Microsoft.FeatureManagement
- Azure App Configuration
- LaunchDarkly / Unleash / ConfigCat

Где это особенно полезно:
- публичные API
- high-traffic сервисы
- SaaS-продукты
- экспериментальные и рискованные фичи

Коротко:
Feature flags превращают релиз из «одного опасного момента» в управляемый процесс.

Это один из самых мощных инструментов для зрелой backend-архитектуры.

👉 Подробнее
🛠 Как оживить протухшую ветку без merge-хаоса

Бывает: вы увлеклись разработкой, прошло пару недель (или месяцев), а основная ветка уже ушла далеко вперёд. В итоге — боль, конфликты и бесконечные merge-коммиты.

В таких случаях может спасати ребейз на свежую ветку:

git pull --rebase origin release/1.2.0


Она подтянет последние изменения из релизной ветки и наложит ваши коммиты поверх, сохранив линейную историю.

Конфликты всё равно придётся разруливать, но по одному — в контексте конкретного коммита, а не в гигантской свалке.

После успешного ребейза пушим с --force-with-lease, чтобы аккуратно обновить удалённую ветку, и продолжаем работать так, как будто отставания и не было.
🔥 Как правильно работать с конфигурацией в .NET

Самый чистый и масштабируемый способ получать настройки в .NET - это Options pattern.

Где живет конфигурация
Настройки приложения могут приходить из разных источников:
- переменные окружения
- JSON-файлы appsettings
- user secrets
- другие configuration providers

Да, можно читать значения напрямую через IConfiguration.
Но это плохо масштабируется:
- легко ошибиться в ключе
- нет типизации
- нет валидации
- код быстро превращается в хаос

Поэтому IConfiguration напрямую лучше не использовать в бизнес-коде.

Options pattern - как правильно
Вместо этого используется Options pattern:

1. Создаешь класс настроек
- один класс = одна логическая группа конфигурации

2. Биндишь его к appsettings.json
- через services.Configure<T>

3. Используешь настройки через DI
- IOptions
- IOptionsSnapshot
- IOptionsMonitor

Плюсы подхода
- строгая типизация
- автокомплит в IDE
- централизованная конфигурация
- проще рефакторить
- можно добавить валидацию через data annotations

Например:
- [Required]
- [Range]
- [EmailAddress]

Это позволяет ловить ошибки конфигурации при старте приложения, а не в продакшене.

Важно знать
Существуют разные интерфейсы:
- IOptions - статические настройки на все время жизни приложения
- IOptionsSnapshot - обновляются на каждый запрос (scoped)
- IOptionsMonitor - отслеживают изменения конфигурации в рантайме

Понимание разницы между ними сильно влияет на корректность архитектуры.

Если пишешь production .NET - Options pattern должен быть стандартом по умолчанию.

https://www.milanjovanovic.tech/blog/how-to-use-the-options-pattern-in-asp-net-core-7
Forwarded from C# (C Sharp) programming
3 простые оптимизации, которые реально ускоряют код

1️⃣ Забирай данные пачкой
Меньше запросов — меньше сетевых задержек.
Вместо десятков запросов — один IN (...).

2️⃣ Делай больше параллельно
Если задачи не зависят друг от друга — выполняй их одновременно.
Асинхронность часто даёт бесплатный прирост скорости.

3️⃣ Кэшируй результаты
Если данные не меняются — не пересчитывай и не запрашивай их заново.
Память дешевле времени.

Никакой магии и сложных алгоритмов — просто базовые приёмы, которые в реальных проектах дают самый заметный эффект.
🔥 На stepik вышел курс, который учит Создавать настоящие AI-сервисы, а не просто запускать скрипты?

Этот практический курс по Python и FastAPI покажет, как собрать полноценное приложение с ИИ, базой данных, автогенерацией контента и Telegram-ботом.

Ты пройдёшь путь от первого HTTP-запроса до рабочего сервиса, который сам генерирует текст через ИИ, сохраняет данные, отправляет результаты по расписанию и отвечает пользователям.

Никакой теории ради теории - только практические шаги, из которых рождается реальный продукт.

🎁 48 часов действует скидка в 40% процентов

👉 Начать учиться на Stepik
Forwarded from C# (C Sharp) programming
✔️ C# стал языком 2025 года по версии TIOBE.

Индекс TIOBE подвел итоги года: звание «Язык 2025 года» досталось C#, который показал рекордный рост популярности (+2.94%)? однако в общем зачете он по-прежнему занимает 5-ю строчку. Абсолютным лидером остается Python с 22.61% долей рынка.

В первой пятерке произошли перестановки: язык C поднялся на 2 место, сместив C++ на 4-ю позицию; 3 место досталось Java, а R вернулся в топ-10. Провал года - Go, который неожиданно сдал позиции, опустившись сразу на 16-е место.

Индекс оценивает популярность технологий на основе поисковых запросов, активности комьюнити и количества обучающих материалов.

https://www.tiobe.com/tiobe-index/
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡️ Автоматическая регистрация Minimal APIs в .NET - без ручного маппинга

Если в проекте 20+ endpoint’ов, app.MapGet/MapPost превращается в ад.
Решение - авторегистрировать endpoints через DI.

Идея:
1) Делаешь общий интерфейс IEndpoint
2) Каждый endpoint реализует его
3) На старте приложения сканируешь сборку, регистрируешь все реализации в DI
4) Достаёшь их из DI и вызываешь MapEndpoints()

Плюсы:
чистый Program.cs
каждый endpoint в отдельном файле
масштабируется без хаоса
легко тестировать и поддерживать

Пример паттерна:


builder.Services.AddEndpoints(typeof(Program).Assembly);

public interface IEndpoint
{
void Map(IEndpointRouteBuilder app);
}

public static class EndpointExtensions
{
public static IServiceCollection AddEndpoints(this IServiceCollection services, Assembly assembly)
{
var endpoints = assembly.DefinedTypes
.Where(t => !t.IsAbstract && !t.IsInterface && typeof(IEndpoint).IsAssignableFrom(t))
.Select(t => ServiceDenoscriptor.Transient(typeof(IEndpoint), t))
.ToArray();

services.TryAddEnumerable(endpoints);
return services;
}

public static void MapEndpoints(this WebApplication app)
{
foreach (var endpoint in app.Services.GetServices<IEndpoint>())
endpoint.Map(app);
}
}
🤖 Open Claude Cowork: AI-партнёр для программирования

Open Claude Cowork — это настольный AI-ассистент, который помогает в программировании, управлении файлами и выполнении задач. Он совместим с Claude Code и предлагает визуальный интерфейс для удобной работы с AI, позволяя легко управлять сессиями и получать результаты в реальном времени.

🚀Основные моменты:
- 🖥️ Настольное приложение с визуальным интерфейсом
- 🤖 AI-партнёр для выполнения задач
- 🔁 Полная совместимость с Claude Code
- 📂 Удобное управление сессиями и историей
- 🔐 Контроль разрешений для безопасных действий

📌 GitHub: https://github.com/DevAgentForge/Claude-Cowork
API Input Validation в .NET: почему FluentValidation лучше, чем Data Annotations

Data Annotations отлично подходят для простых правил:

[Required] - ок
[MaxLength(50)] - норм

Но как только тебе нужно что-то “умнее”, начинается боль:

- проверить данные в базе
- валидировать по настройкам из appsettings.json
- вызвать сервис и принять решение динамически

Data Annotations упираются в потолок, потому что Attribute - это статичная штука.
Туда не получится нормально прокинуть зависимости через DI.

И вот здесь FluentValidation реально сияет

Почему:
FluentValidation-валидаторы - это обычные классы, которые регистрируются в DI контейнере.
А значит, внутрь можно инжектить что угодно:

- сервисы
- конфиги
- репозитории
- кэш
- внешние API

Пример:
нужно проверить, что CouponCode валиден через IPricingService?
Просто инжектишь IPricingService в конструктор валидатора и делаешь проверку.

В итоге валидация превращается из “статической проверки полей”
в полноценный слой логики - динамический, умный и расширяемый.

FluentValidation = правильная валидация для реального продакшена.
This media is not supported in your browser
VIEW IN TELEGRAM
🖥 Многопоточность в .NET часто сводят к lock. Но в реальных системах этого недостаточно — особенно под нагрузкой, в легаси-коде и распределённых сценариях.

📕 На открытом уроке разберём, какие инструменты действительно есть в .NET и как выбирать подходящий примитив под конкретную задачу. Рассмотрим Monitor, Mutex, Semaphore, а также другие примитивы из System.Threading: ReaderWriterLockSlim, Barrier, ManualResetEventSlim, SpinLock.

❗️ Вы увидите практические примеры, типовые ошибки и узнаете, где блокировки становятся узким местом. Урок будет полезен разработчикам, работающим с высоконагруженными системами и легаси-кодом, а также тимлидам, которые проектируют архитектуру и отвечают за производительность.

📣 Встречаемся 27 января в 20:00 МСК в преддверии старта курса «C# Developer. Professional». Регистрация открыта: https://otus.pw/t6Xj/
✔️ C# может прокачать collection expressions: “аргументы при создании коллекции”

Есть прикольное предложение в csharplang: сделать так, чтобы в collection expressions (`[a, b, c]`) можно было передавать аргументы в создание коллекции.

Проблема сейчас:
Postgres-стайл удобный синтаксис уже есть:

List<int> xs = [1, 2, 3];

Но если тебе важно задать, например, capacity (чтобы не было лишних realloc внутри списка), то приходится писать “старым способом”:

var xs = new List<int>(capacity: 32) { 1, 2, 3 };

Предлагаемое решение:
добавить возможность передавать аргументы прямо в collection expression:

List<int> xs = [args(capacity: 32); 1, 2, 3];

То есть:
- args(...) - это аргументы для конструктора / create-метода
- после ; - элементы коллекции

Зачем это нужно:
- можно сохранить суперкороткий синтаксис [ ... ]
- но при этом контролировать создание коллекции (capacity, comparer и т.д.)
- меньше лишних аллокаций → быстрее в hot-path коде

Если фича дойдёт до релиза, это будет реально удобный апгрейд синтаксиса коллекций в C#.

https://github.com/dotnet/csharplang/blob/main/proposals/collection-expression-arguments.md
Please open Telegram to view this post
VIEW IN TELEGRAM