C# 1001 notes
رفتن به کانال در Telegram
Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого. admin - @haarrp
نمایش بیشتر6 539
مشترکین
-324 ساعت
-17 روز
-230 روز
آرشیو پست ها
6 539
Почти каждый разработчик допускал эту ошибку.
Что не так с этим кодом?
На первый взгляд всё кажется логичным:
🔸API-эндпоинт регистрации пользователя вызывает
UserService
🔸UserService сохраняет пользователя в базу и вызывает EmailService
🔸EmailService через SmtpClient отправляет письмо
Но если присмотреться, метод SendWelcomeEmail объявлен как async void.
В чём проблема с async void?
Вот суть:
❌ async void делает невозможным отлов исключений.
Если внутри SendEmailAsync() произойдёт исключение — catch его не перехватит.
Вместо этого приложение может тихо упасть или начать вести себя непредсказуемо.
Почему так происходит?
Методы async void не возвращают Task, поэтому вызывающий код не может их await-ить и обрабатывать ошибки.
Исключения из async void проходят мимо стандартных механизмов обработки.
Правильный подход:
✅Всегда возвращай Task
Запомни: async void допустим только для обработчиков событий, где возвращаемый void обязателен.6 539
😈 Хитрая задачка на C# — замыкания и ловушка в цикле
Что выведет этот код?
var actions = new List<Action>();
for (int i = 0; i < 5; i++)
{
actions.Add(() => Console.WriteLine(i));
}
foreach (var action in actions)
{
action();
}
На первый взгляд кажется, что будет:
0
1
2
3
4
Но на самом деле вывод:
5
5
5
5
5
💡 Почему?
Все лямбды замкнулись на одну и ту же переменную i, и когда они выполняются — i уже стало 5.
✅ Как исправить:
for (int i = 0; i < 5; i++)
{
int copy = i;
actions.Add(() => Console.WriteLine(copy));
}
Теперь всё работает как ожидается.
🧠 Замыкания в C# захватывают переменные, а не их значения! Аккуратнее с циклами и лямбдами.6 539
😱💻 Хотите прокачать архитектурные скилы и стать востребованным fullstack-разработчиком?
Пройдите вступительный тест и получите бесплатные уроки курса «C# ASP.NET Core разработчик» от OTUS!
👉 Пройти тест: https://otus.pw/gmbX/
🚀 Зарядите карьеру: увеличьте доход, берите сложные проекты и работайте с современным стеком!
Всего за 6 месяцев вы научитесь:
• Разрабатывать веб-приложения на ASP.NET Core, рассматривая ASP.NET подробно, со всеми его механизмами
• Создавать различные технологии межсервисного взаимодействия + реалтайм с клиентским приложением
•Интегрировать фронтенд (ReactJS + JavaScript+Typescript) с бэкендом
• Тестировать приложения: интеграционные и нагрузочные тесты
• Автоматизировать процессы с CI/CD и Kubernetes
• Проектировать микросервисы и освоить event-driven архитектуру
🎁 Бонус: После теста — доступ к урокам!
👉 Проверьте свои силы прямо сейчас: https://otus.pw/gmbX/?erid=2W5zFJd7K3v
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
6 539
🔥 .NET Aspire: как упростить Service Discovery в микросервисах
Вместо ручной настройки адресов и портов, фреймворк .NET Aspire позволяет упростить обнаружение сервисов с помощью декларативного подхода.
🔹 Конфигурация через
.AddProject() и .WithReference()
🔹 Сервисы автоматически "обнаруживаются" и подключаются
🔹 Поддержка локальной разработки, контейнеров и облака
🔹 Логи, метрики, health checks — встроены
📌 Aspire — это не просто упрощение разработки, это фундамент для масштабируемых .NET-приложений.
🧠 Полный разбор — в блоге:
[how-dotnet-aspire-simplifies-service-discovery](https://www.milanjovanovic.tech/blog/how-dotnet-aspire-simplifies-service-discovery)
Подпишись, чтобы не пропускать важные новинки .NET и облачной разработки.6 539
Хотите научиться создавать современные приложения на C# и понять, как работает объектно-ориентированное программирование?
📗 Присоединяйтесь к открытому уроку «Основы ООП на примере C#» 22 июля в 20:00 МСК. Мы разберем:
- Основные принципы ООП: инкапсуляция, наследование, полиморфизм и абстракция.
- Как эти принципы реализуются в языке C#.
- Практические примеры, синтаксис и типичные ошибки начинающих.
🔴 Этот урок — отличная тренировка перед курсом «C# Developer» от OTUS, который стартует совсем скоро. Все участники получат скидку на обучение.
Записаться на вебинар → https://otus.pw/34qD/?erid=2W5zFGwC6ba
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
6 539
Какое исключение выдается, если протокол, поддерживаемый префиксом URI, недействителен?
6 539
💻 Асинхронная обработка данных в высоконагруженных системах 🚀
🔥 29 июля в 20:00 мск — открытый вебинар в OTUS.
На вебинаре рассмотрим:
- Почему асинхронная архитектура — ключ к масштабируемости и высокой производительности?
- Как эффективно использовать очереди сообщений, веб-сокеты и другие инструменты асинхронного взаимодействия?
- Пример реального архитектурного решения: от веб-сервера до брокера сообщений и БД.
- Как найти узкие места в архитектуре и устранить их для стабильной работы высоконагруженных сервисов.
🎓 После вебинара вы:
- Поймёте принципы асинхронной архитектуры и её влияние на производительность.
- Освоите методы асинхронной обработки данных для масштабируемых систем.
- Получите реальные примеры архитектурных решений для внедрения в свои проекты.
- Узнаете, как избегать узких мест и создавать отказоустойчивые системы.
🔧 Присоединяйтесь, чтобы улучшить архитектурные навыки и начать строить системы, готовые к высокой нагрузке!
👉 Регистрация https://otus.pw/8ta1/?erid=2W5zFJjJ3DS
Бесплатное занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
6 539
📌 PolySharp — удобный способ использовать новые фичи C# на старых версиях .NET. Этот NuGet-пакет работает как source-генератор, автоматически подбирая нужные полифиллы в зависимости от целевой платформы. Для работы достаточно добавить ссылку на PolySharp, установить последнюю версию C# и можно писать современный код даже для .NET Framework или UWP.
Инструмент обладает умной генерацией только необходимых типов. Например, если компилятору C# 13 нужен
[IsExternalInit] для init-only свойств, PolySharp создаст его за кулисами. При этом он не трогает фичи, требующие поддержки рантайма, но покрывает огромный пласт синтаксических улучшений — от nullable-аннотаций до интерполированных строковых обработчиков.
🤖 GitHub
@csharp_ci6 539
🔐 Блог DevelopersVoice выпустил отличный гайд по **10 главным уязвимостям веб‑приложений с примерами на .NET.
Что внутри:
• Инъекции и XSS
• Ошибки аутентификации
• Уязвимые зависимости
• SSRF и плохая конфигурация
• Проблемы с логированием и безопасным дизайном
📌 Всё с практическими советами: как обнаружить, как исправить, как не допустить.
Полный гайд тут: https://developersvoice.com/blog/secure-coding/owasp-top-ten
#OWASP #SecureCoding #DotNet #WebSecurity #DevTips
6 539
🖥 Топ-10 ошибок .NET‑разработчиков
Если ты пишешь на .NET — возможно, ты хотя бы раз совершал одну из этих архитектурных (или просто утомительных) ошибок. Вот список анти-паттернов.
1. Blazor вместо React
Переизобретать веб на C# ради UI? Ты не Google. Если нужен зрелый фронт, бери то, что уже доказало свою масштабируемость.
2. Serverless Azure Functions на одном App Service Plan
"О, это же серверлесс!" — пока не замечаешь, что всё сидит на одном сервисе. Масштабируемость мнимая, расходы настоящие.
3. Самодельный MVC поверх Minimal APIs
Зачем ты пишешь свою обвязку маршрутов, контроллеров и зависимостей, если MVC уже всё это умеет?
4. Хранимки для CRUD
Хранимки — не антипаттерн, но когда их 200 штук для банального Insert/Update/Delete — это просто ORM с человеческим лицом, только сложнее.
5. "Юнит-тесты", которым нужен деплой БД
Это не юнит-тесты. Это интеграционные, а если быть честным — "fragile-тесты".
6. AutoMapper
В теории красиво, в проде — «а почему здесь null?». Иногда проще написать руками и понять, что происходит.
7. Игнор Microsoft Orleans
Если делаешь real-time, pub/sub, воркеры — Orleans стоит хотя бы попробовать. Он закрывает много боли, которую ты иначе сам будешь собирать по кускам.
8. Начинать с "микросервисов"
Монолит — не зло. Зло — это 12 проектов в solution, которые общаются через HTTP и собираются 10 минут.
9. gRPC для фронта
Если у тебя браузер → JS → gRPC → base64 → JSON — просто остановись. Возьми REST или GraphQL и живи спокойно.
10. Razor Pages вместо MVC
Да, они проще на старте. Но когда проект растёт, ты захочешь нормальное разделение по слоям, маршрутам и структуре.
🧠 Вывод: не все возможности .NET надо использовать. Иногда сила — в простоте.
C чем согласны ? Что добавили бы ?#dotnet #csharp #webdev #архитектура #программирование
6 539
⚠️ Как вы обрабатываете ошибки в C#?
Многие используют исключения для управления потоком и быстрого фейла. Но в C# метод не сообщает, какие именно исключения он может выбросить — это не видно в сигнатуре.
🔍 Мой подход:
Исключения — только для исключительных ситуаций.
Если метод может ожидаемо провалиться, пусть это будет явно.
✅ Используйте Result-паттерн:
— Метод возвращает
Result<T> вместо выбрасывания исключения
— Caller обязан проверить IsSuccess и обработать ошибку
— Код становится предсказуемее и легче тестируется
— Дополнительно: пропускная способность может быть выше, чем при throw/catch
Пример:
Result<User> result = userService.FindById(id);
if (!result.IsSuccess)
return Error(result.Error);
Подробнее6 539
👩💻 🎯 Открытый урок «Асинхронность в C#: за гранью await. Паттерны, ошибки и оптимизация для профессионалов».
🗓 17 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «C# Developer. Professional».
Что будет на вебинаре:
✔️ Разбор сложных сценариев: цепочки задач, параллельный async, комбинирование с параллелизмом (Task, Parallel, async).
✔️ Распространенные ошибки (deadlocks, async void, контексты синхронизации) и как их точно избегать.
✔️ Паттерны: CancellationTokens, ValueTask, IAsyncDisposable, кастомные awaiterы (обзорно).
✔️ Когда и как измерять производительность async кода, что может стать узким местом.
✔️ Best practices для реальных высоконагруженных сценариев.
Кому будет полезно:
- Разработчикам C# с опытом (Mid+/Senior), которые активно используют async/await.
- Тем, кто сталкивался с непонятными блокировками или проблемами производительности в асинхронном коде.
- Тем, кто хочет писать более надежный и эффективный асинхронный код.
🔗 Ссылка на регистрацию: https://otus.pw/SIHc/
6 539
🧠 .NET-задача для продвинутых: потокобезопасная очередь с приоритетами и отменой задач
Задача:
Реализуйте асинхронный планировщик задач с приоритетами и возможностью отмены. Требования:
1. Есть очередь задач (`Func<CancellationToken, Task>`), каждая с целочисленным приоритетом (0 — самый высокий).
2. Задачи выполняются параллельно, но не более
N одновременно.
3. Если приходит задача с более высоким приоритетом, и нет свободных слотов, она может вытеснить задачу с самым низким приоритетом.
4. Вытеснённая задача должна быть отменена (через `CancellationToken`), и её ресурсы — корректно освобождены.
5. Код должен быть потокобезопасным и устойчивым к гонкам.
Дополнительно:
- Используйте PriorityQueue, SemaphoreSlim, CancellationTokenSource
- Не допускайте deadlock’ов
- Обеспечьте корректное завершение планировщика по команде StopAsync()
Пример API:
public class PriorityTaskScheduler
{
public PriorityTaskScheduler(int maxParallelism);
public Task EnqueueAsync(Func<CancellationToken, Task> task, int priority);
public Task StopAsync();
}
@csharp_1001_notes6 539
👩💻 🎯 Открытый урок «Асинхронность в C#: за гранью await. Паттерны, ошибки и оптимизация для профессионалов».
🗓 17 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «C# Developer. Professional».
Что будет на вебинаре:
✔️ Разбор сложных сценариев: цепочки задач, параллельный async, комбинирование с параллелизмом (Task, Parallel, async).
✔️ Распространенные ошибки (deadlocks, async void, контексты синхронизации) и как их точно избегать.
✔️ Паттерны: CancellationTokens, ValueTask, IAsyncDisposable, кастомные awaiterы (обзорно).
✔️ Когда и как измерять производительность async кода, что может стать узким местом.
✔️ Best practices для реальных высоконагруженных сценариев.
Кому будет полезно:
- Разработчикам C# с опытом (Mid+/Senior), которые активно используют async/await.
- Тем, кто сталкивался с непонятными блокировками или проблемами производительности в асинхронном коде.
- Тем, кто хочет писать более надежный и эффективный асинхронный код.
🔗 Ссылка на регистрацию: https://otus.pw/SIHc/
6 539
Устали править копипастные участки кода и бороться с хаосом в проекте?
⏺️ Приглашаем на открытый урок «Переиспользуемый код на C#: архитектурный подход» 15 июля в 20:00 МСК. Разберём, как строить приложение по принципам SOLID, DRY, KISS и YAGNI и избавляться от дублирования на уровне архитектуры. Вы увидите, как декомпозировать систему на слои, внедрять зависимости через абстракции и собирать «Lego-приложение» для разных интерфейсов.
🔴 Встречаемся 15 июля в 20:00 МСК.
➡️ Успейте зарегистрироваться на урок количество участников ограничено: https://otus.pw/QsiE/?erid=2W5zFJGhdct
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
6 539
🎯 Using .NET Aspire With the Docker Publisher — практическое руководство от Milan Jovanović
.NET Aspire — это современный фреймворк от Microsoft для создания облачных микросервисов. В статье показано, как автоматически интегрировать Docker Compose в .NET‑приложение с помощью нового инструмента — Aspire Docker Publisher.
✅ Что вы узнаете:
1. Как описать окружение прямо в C#:
builder.AddDockerComposeEnvironment("aspire-docker-demo");
var postgres = builder.AddPostgres("database").WithDataVolume();
var redis = builder.AddRedis("cache");
var webApi = builder.AddProject<Projects.Web_Api>("web-api")
.WithReference(postgres).WaitFor(postgres)
.WithReference(redis).WaitFor(redis);
builder.Build().Run();
2. Как опубликовать проект:
dotnet tool install --global aspire.cli --prerelease
aspire publish -o docker-compose-artifacts
После чего автоматически создаётся docker-compose.yml и .env.
3. Что входит в результат:
- Готовый docker-compose.yml со всеми зависимостями
- Поддержка портов, переменных среды, volume и сетей
- Полная инфраструктура, которую можно деплоить хоть на VPS
4. Как это работает на проде:
- Всё, что нужно: скопировать артефакты → docker compose up -d
- Можно легко обернуть через Nginx или Traefik, подключить SSL
🧠 Почему это удобно:
- Не нужно вручную писать YAML — всё в коде
- Повышается воспроизводимость и читаемость инфраструктуры
- Упрощает переход от локальной разработки к боевому деплою
🔗 Статья: www.milanjovanovic.tech/blog/using-dotnet-aspire-with-the-docker-publisher6 539
Трюк: добавление элементов в словарь со списками через `??=`
var dict = new Dictionary<string, List<int>>();
string key = "numbers";
int item = 42;
// Обычный способ:
if (!dict.TryGetValue(key, out var list))
{
list = new List<int>();
dict[key] = list;
}
list.Add(item);
// Короткий трюк:
(dict[key] ??= new List<int>()).Add(item);
Разбор:
- При обращении к dict[key] отсутствующий ключ вернёт default(List<int>), то есть null.
- Оператор ??= проверяет левую часть на null и, если она null, присваивает справа новое значение.
- В нашем случае, если dict[key] был null, создаётся новый List<int> и сразу сохраняется в словаре.
- После этого метод .Add(item) вызывается уже на существующем списке.
- В результате за одну строчку мы и проверили наличие, и создали новый список при необходимости, и добавили элемент.6 539
⁉️ Тормозит карьерный рост? Упираетесь в потолок с текущими навыками на C#? Новые проекты ускользают, а вы застряли на уровне Middle?
🔥 Пройдите тест! 💻 Ответьте на 32 вопроса и узнайте, достаточно ли у вас знаний, для обучения на онлайн-курсе «C# Developer. Professional» от OTUS.
Вас ждут реальные проекты в Scrum-командах, продвинутый уровень работы с C#, освоение SQL и NoSQL, кэширование, Unit-тесты и CI/CD.
🦾 Пора стать тем самым разработчиком, которого компании хантят друг у друга. Нужно только перейти на принципиально новый уровень.
👉 Пройдите тест и присоединяйтесь к группе: https://otus.pw/WEvA/
#реклама
О рекламодателе
6 539
🖥Быстрая сортировка (QuickSort) с использованием рекурсии
Проблема: cортировка больших массивов может быть неэффективной при использовании простых алгоритмов, таких как сортировка пузырьком или вставками.
Решение: Автор в книге Algorithms and Data Structures for OOP With C# демонстрирует реализацию QuickSort — одного из самых эффективных алгоритмов сортировки на практике, с рекурсивным разбиением массива.
Пример кода:
public class QuickSortExample
{
public void QuickSort(int[] arr, int low, int high)
{
if (low < high)
{
int pi = Partition(arr, low, high);
QuickSort(arr, low, pi - 1);
QuickSort(arr, pi + 1, high);
}
}
private int Partition(int[] arr, int low, int high)
{
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j < high; j++)
{
if (arr[j] < pivot)
{
i++;
(arr[i], arr[j]) = (arr[j], arr[i]);
}
}
(arr[i + 1], arr[high]) = (arr[high], arr[i + 1]);
return i + 1;
}
}
Преимущества:
— Быстрая сортировка даже больших наборов данных
— Средняя сложность O(n log n)
— Эффективное использование памяти за счет рекурсии6 539
🐢 Столкнулись с «тормозным» C#-кодом? Медленные алгоритмы могут растянуть выполнение задачи на минуты вместо миллисекунд.
📅 Приглашаем на открытый урок «Анализ сложности алгоритмов и сортировка на C#» 3 июля в 20:00 МСК.
Разберём, что такое Big O, какие факторы влияют на скорость, и на практике напишем пузырьковую, вставками и другие сортировки.
Вы увидите, как измерять время выполнения, сравнивать производительность и выбирать самый эффективный алгоритм. После занятия ваш код станет быстрее, а техническое интервью — проще.
Регистрируйтесь сейчас — урок проходит перед стартом курса «C# Developer»: https://otus.pw/yQzK/?erid=2W5zFJSuoQ4
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
اکنون در دسترس! پژوهش تلگرام ۲۰۲۵ — مهمترین بینشهای سال 
