ar
Feedback
C# 1001 notes

C# 1001 notes

الذهاب إلى القناة على Telegram

Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого. admin - @haarrp

إظهار المزيد
6 617
المشتركون
+124 ساعات
+537 أيام
+4730 أيام
أرشيف المشاركات
👩‍💻 🎯 Открытый урок «Асинхронность в C#: за гранью await. Паттерны, ошибки и оптимизация для профессионалов». 🗓 17 июля в
👩‍💻 🎯 Открытый урок «Асинхронность в 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/

Устали править копипастные участки кода и бороться с хаосом в проекте? ⏺️ Приглашаем на открытый урок «Переиспользуемый код н
Устали править копипастные участки кода и бороться с хаосом в проекте?  ⏺️ Приглашаем на открытый урок «Переиспользуемый код на C#: архитектурный подход» 15 июля в 20:00 МСК. Разберём, как строить приложение по принципам SOLID, DRY, KISS и YAGNI и избавляться от дублирования на уровне архитектуры. Вы увидите, как декомпозировать систему на слои, внедрять зависимости через абстракции и собирать «Lego-приложение» для разных интерфейсов. 🔴 Встречаемся 15 июля в 20:00 МСК. ➡️ Успейте зарегистрироваться на урок количество участников ограничено: https://otus.pw/QsiE/?erid=2W5zFJGhdct  Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

🎯 Using .NET Aspire With the Docker Publisher — практическое руководство от Milan Jovanović .NET Aspire — это современный фр
🎯 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-publisher

Трюк: добавление элементов в словарь со списками через `??=`

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) вызывается уже на существующем списке. - В результате за одну строчку мы и проверили наличие, и создали новый список при необходимости, и добавили элемент.

⁉️ Тормозит карьерный рост? Упираетесь в потолок с текущими навыками на C#? Новые проекты ускользают, а вы застряли на уровне
⁉️ Тормозит карьерный рост? Упираетесь в потолок с текущими навыками на C#? Новые проекты ускользают, а вы застряли на уровне Middle? 🔥 Пройдите тест! 💻 Ответьте на 32 вопроса и узнайте, достаточно ли у вас знаний, для обучения на онлайн-курсе «C# Developer. Professional» от OTUS. Вас ждут реальные проекты в Scrum-командах, продвинутый уровень работы с C#, освоение SQL и NoSQL, кэширование, Unit-тесты и CI/CD. 🦾 Пора стать тем самым разработчиком, которого компании хантят друг у друга. Нужно только перейти на принципиально новый уровень. 👉 Пройдите тест и присоединяйтесь к группе: https://otus.pw/WEvA/ #реклама О рекламодателе

🖥Быстрая сортировка (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) — Эффективное использование памяти за счет рекурсии

🐢 Столкнулись с «тормозным» C#-кодом? Медленные алгоритмы могут растянуть выполнение задачи на минуты вместо миллисекунд. 📅
🐢 Столкнулись с «тормозным» C#-кодом? Медленные алгоритмы могут растянуть выполнение задачи на минуты вместо миллисекунд.  📅 Приглашаем на открытый урок «Анализ сложности алгоритмов и сортировка на C#» 3 июля в 20:00 МСК. Разберём, что такое Big O, какие факторы влияют на скорость, и на практике напишем пузырьковую, вставками и другие сортировки. Вы увидите, как измерять время выполнения, сравнивать производительность и выбирать самый эффективный алгоритм. После занятия ваш код станет быстрее, а техническое интервью — проще. Регистрируйтесь сейчас — урок проходит перед стартом курса «C# Developer»: https://otus.pw/yQzK/?erid=2W5zFJSuoQ4 Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

🖥 Задача «Перехват исключений и потеря контекста» (C# 12) Дан код:

using System;
using System.Runtime.ExceptionServices;

class Program
{
    static void Main()
    {
        try
        {
            Console.WriteLine(Foo());
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Catch: {ex.Message}");
        }
    }

    static int Foo()
    {
        try
        {
            return Bar();
        }
        finally
        {
            throw new Exception("finally in Foo");
        }
    }

    static int Bar()
    {
        try
        {
            throw new Exception("error in Bar");
        }
        finally
        {
            Console.WriteLine("Bar finally executed");
        }
    }
}
Вопросы: • Что напечатает программа и почему? • В каком порядке выполняются блоки try / finally? • Какая из двух ошибок дойдёт до catch, а какая потеряется? • Как изменить код, чтобы не терять информацию о первой ошибке? Разбор: • Bar бросает Exception("error in Bar"). Прежде чем исключение покинет метод, выполняется его finally, выводя Bar finally executed. • Управление переходит в Foo. Там срабатывает finally, который бросает новое исключение ("finally in Foo"). • По правилам CLR новое исключение из finally заменяет текущее. Первая ошибка пропадает. • В Main перехватывается только «finally in Foo». Консольный вывод: Bar finally executed Catch: finally in Foo Как сохранить обе ошибки Обернуть второе исключение так, чтобы первая причина не потерялась, например:

finally
{
    var pending = new Exception("finally in Foo");
    throw new AggregateException("Foo failed", pending);
}
или переслать исходное исключение через ExceptionDispatchInfo: Exception pending = null; static int Foo() { try { return Bar(); } catch (Exception ex) { pending = ex; // сохраняем первую причину throw; } finally { if (pending != null) ExceptionDispatchInfo.Capture(pending).Throw(); } }``` Так ни одна ошибка не будет потеряна, а отладка станет нагляднее.

Реферальная программа для тех, кто не работает в Ozon: порекомендуйте C#-разработчика уровня senior и заработайте 150 000 ₽.
Реферальная программа для тех, кто не работает в Ozon: порекомендуйте C#-разработчика уровня senior и заработайте 150 000 ₽. Посмотреть вакансии, которые включает программа: https://s.ozon.ru/rja14Mz

In-memory кэш в .NET: плюсы и минусы ✅ Плюсы: • Очень быстрый • Легко реализуется • Не требует внешних зависимостей ⚠️ Минусы
In-memory кэш в .NET: плюсы и минусыПлюсы: • Очень быстрый • Легко реализуется • Не требует внешних зависимостей ⚠️ Минусы: • Данные теряются при перезапуске • Работает только в пределах одного инстанса • Нет шаринга между приложениями 📌 Нужно больше — переходите на распределённый кэш. Redis — топовый выбор, и в .NET есть два стабильных клиента: • StackExchange.RedisMicrosoft.Extensions.Caching.StackExchangeRedis 📘 Хотите понять, когда и как использовать оба подхода? Вот полный гайд: https://milanjovanovic.tech/blog/caching-in-aspnetcore-improving-application-performance

💣 Как настроить отказоустойчивое хранилище данных? Дарим гайд за прохождение теста по HighLoad! 🏆 Пройди тест из 29 вопросо
💣 Как настроить отказоустойчивое хранилище данных? Дарим гайд за прохождение теста по HighLoad! 🏆 Пройди тест из 29 вопросов, проверь свой уровень знаний и получи файл “Как настроить отказоустойчивое хранилище данных“! Тест проводится в рамках курса Highload Architect 👉 Пройти тест и забрать файл: https://otus.pw/348d/?erid=2W5zFJdK4JC Если успешно пройдешь тест, то так же сможешь забронировать место в группе по выгодной цене! 🎫 Курс можно приобрести в рассрочку Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

[Best Practice] Явная конфигурация приложений ASP.NET Core В большинстве существующих .NET-проектов конфигурация оказывается
[Best Practice] Явная конфигурация приложений ASP.NET Core В большинстве существующих .NET-проектов конфигурация оказывается неочевидной, хотя в экосистеме .NET уже есть всё необходимое для ясной и понятной настройки ASP.NET Core веб-приложений с DI. Как устроена конфигурация ASP.NET Core - Источники (в порядке приоритета): 1. Host configuration 2. appsettings.json 3. appsettings.{Environment}.json 4. User secrets (в среде Development) 5. переменные окружения 6. аргументы командной строки При дублировании ключей побеждает источник, указанный позже :contentReference[oaicite:0]{index=0}. Выбор способа доступа к настройкам - Через IConfiguration - Через IOptions<T> / IOptionsMonitor<T> Предпочтение паттерну Options даёт типобезопасный доступ к группам настроек и делает их использование очевидным :contentReference[oaicite:1]{index=1}. Где хранить разные параметры - `appsettings.json` — общие настройки (без секретов). - `appsettings.{Environment}.json` — переопределения для конкретного окружения. - User Secrets (`secrets.json`) — локальные секреты (пароли, ключи API); не используйте appsettings.json или appsettings.Development.json для них :contentReference[oaicite:2]{index=2}. - Azure Key Vault — производственные секреты через builder.Configuration.AddAzureKeyVault(...) :contentReference[oaicite:3]{index=3}. - Переменные окружения и CLI — для срочных или разовых переопределений. Рекомендации по внедрению - Избегайте дублирования ключей — задавайте значение только там, где оно действительно меняется. - В README укажите, что разработчикам нужно получить secrets.json из менеджера паролей и настроить User Secrets. - В IaC-скриптах чётко обозначьте необходимые секреты и параметры для каждого окружения. Преимущества подхода - Новым участникам проекта легко разобраться в конфигурации — каждый ключ встречается в одном месте. - Возрастает поддерживаемость и прозрачность настроек. - Упрощается автоматизация развёртывания (IaC): сразу видно, какие секреты и параметры требуются. Читать

👶 Junior developer пишет: notInactive, tempBool 🧑 Middle developer пишет: hadSubscriptionOnceUponATime 🧓 Senior developer
👶 Junior developer пишет: notInactive, tempBool 🧑 Middle developer пишет: hadSubscriptionOnceUponATime 🧓 Senior developer пишет: hasSubscription, isActive 🤔 Почему так происходит? 👉 Потому что булевы переменные — просты по сути, но часто используются неинтуитивно, что делает код запутанным и плохо поддерживаемым. Вот 7 простых правил, как работать с булевыми значениями в C# и резко улучшить читаемость вашего кода: 1. 🚫 Избегайте двойных отрицаний ❌ user.IsNotActiveuser.IsActiveuser.HasNoDeptuser.HasDeptcreditCard.IsNotExpiredcreditCard.IsExpired Двойные отрицания сбивают с толку и делают логику трудной для чтения. 2. ✅ Используйте понятные префиксы ✅ Is: user.IsActiveHas: user.HasDeptShould: order.ShouldBeCanceled Префиксы мгновенно раскрывают назначение переменной. 3. 🔤 Предпочитайте единственное число ❌ areUsershasUsers Единственное число делает значение ясным и конкретным. 4. 🎯 Используйте прилагательные для описания состояния ❌ CancelOrderIsOrderCanceled Булевы переменные должны описывать состояние, а не действие. 5. ⏱ Используйте настоящее время ❌ card.WasExpiredcard.IsExpired Текущие состояния — проще и универсальнее в коде. 6. 🔁 Принцип раннего возврата (Return Early) Пишите условия и булевы проверки так, чтобы код читался сверху вниз, как история — коротко, логично, понятно. 7. ⚠️ Не передавайте булевы параметры ❌ SendEmail(true)SendEmail(SendMode.Immediate) Используйте перечисления или именованные константы — они понятны без документации. 📌 Вывод: Хорошие имена булевых переменных — это не косметика, а основа читаемости и архитектурной чистоты. Хорошо названный isActive понятнее, чем любые комментарии и тесты. 💬 А ты какие правила используешь для наименования булевых переменных? Делись в комментариях 👇

Repost from C++ Academy
🚀 Разработчик показал движок на C, который работает в 14 раз быстрее Unity в браузере — и теперь доступна онлайн-демо. Многие не поверили в заявленную разницу в производительности, поэтому он выложил демо в открытый доступ. Сравнение проводится с реальным Unity-проектом, выложенным на GitHub. 🛠️ C-движок демонстрирует: • Существенно более высокую FPS в браузере • Минимальную просадку при рендеринге • Низкий overhead по сравнению с WebAssembly-сборкой Unity 💬 Автор пока не решил, выкладывать ли исходники C-версии — рассматривает вариант лицензии CC (non-commercial). 🔗 Демо: https://cgamedev.com/ 🔗 Код: https://github.com/gabrieldechichi/unity_webglperftest @cpluspluc

💣 Большая сила - большая ответственность. А ты справишься с тестом по HighLoad? 🏆 Пройди тест из 29 вопросов, проверь свой
💣 Большая сила - большая ответственность. А ты справишься с тестом по HighLoad? 🏆 Пройди тест из 29 вопросов, проверь свой уровень знаний и получи скидку на онлайн-курс «Highload Architect» от OTUS! Если успешно пройдешь тест, сможешь забронировать место в группе по выгодной цене! 🎫 Курс можно приобрести в рассрочку 👉 Пройти тест и забрать скидку: https://otus.pw/pdy8/?erid=2W5zFGJXEcY Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

🗂️ Entity Framework Core — ORM нового поколения для работы с БД. Этот инструмент от Microsoft кардинально меняет подход к вз
🗂️ Entity Framework Core — ORM нового поколения для работы с БД. Этот инструмент от Microsoft кардинально меняет подход к взаимодействию с реляционными и NoSQL базами данных. Для работы инструмент предоставляет мощный слой абстракции, позволяя работать с данными как с объектами, автоматизируя CRUD-операции и миграции схемы. EF Core поддерживает широкий пласт СУБД: от классических SQL Server и PostgreSQL до документоориентированной Cosmos DB. Для SQLite-разработчиков есть отдельный оптимизированный провайдер Microsoft.Data.Sqlite. 🤖 GitHub

🤖 Два подхода DDD: Rich Model vs Anemic Model Приглашаем на открытый урок. 🗓 24 июня в 20:00 МСК 🆓 Бесплатно. Урок в рамка
🤖 Два подхода DDD: Rich Model vs Anemic Model  Приглашаем на открытый урок. 🗓 24 июня в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «C# Developer Professional». На вебинаре: ✔️  Разбор концепций: чем анемичная модель (Anemic Model) отличается от богатой (Rich Model) ✔️  Рассмотрим, когда что выбрать ✔️  Оценим преимущества и недостатки каждой из моделей Кому будет полезно: - Всем, кто стремится глубже понять DDD - .NET-разработчикам, проектирующим сложные системы с долгосрочной поддержкой - Студентам, изучающим паттерны проектирования и чистую архитектуру Чему научатся участники по итогам вебинара: - Понимать, когда код попадает в антипаттерн Anemic Model - Проектировать сущности с бизнес-логикой внутри - Выбирать компромиссы: скорость разработки (Anemic) vs гибкость/безопасность (Rich). 🔗 Ссылка на регистрацию: https://otus.pw/lgGf/ #реклама О рекламодателе

⚡️ Если ты запускаешь десяток терминалов для старта приложения С .NET Aspire можно запускать backend, frontend и все зависимо
+1
⚡️ Если ты запускаешь десяток терминалов для старта приложения С .NET Aspire можно запускать backend, frontend и все зависимости одновременно — быстро и удобно! Смотри, как это сделать: justkeepcoding.tech/blog/integrating-angular-into-dotnet-aspire

Балансировка и геораспределение: как создать быстрое и надёжное приложение для всего мира На вебинаре разберём, как крупные к
Балансировка и геораспределение: как создать быстрое и надёжное приложение для всего мира На вебинаре разберём, как крупные компании — такие как Netflix, Amazon и другие — делают свои сервисы доступными для пользователей по всему миру без задержек и сбоев. На вебинаре вы: — Как работают балансировщики и «умные» прокси. — Что такое геораспределение и зачем оно критично для масштабируемых сервисов. — Как грамотно распределять трафик между дата-центрами. — Частые ошибки при проектировании глобальных систем — и как их избежать. 👉 Регистрация и подробности о курсе Highload Architect: https://tglink.io/e860f3379195?erid=2W5zFGLzfAg Бесплатное занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов. Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

🌺 Radzen Blazor Components — 90+ UI-компонентов для Blazor. Этот набор открытых компонентов позволяет быстро собирать интерф
🌺 Radzen Blazor Components — 90+ UI-компонентов для Blazor. Этот набор открытых компонентов позволяет быстро собирать интерфейсы на Blazor без зависимостей от JavaScript-фреймворков. Все элементы нативные для Blazor, написанные на C#, что обеспечивает полную интеграцию с экосистемой .NET. Проект активно развивается: новые компоненты появляются регулярно, а не ждут квартальных релизов. Для коммерческой разработки доступна платная подписка с расширенной поддержкой, но базовая функциональность остаётся бесплатной под лицензией MIT. 🤖 GitHub @csharp_ci