C# Portal | Программирование
13.3K subscribers
1.28K photos
131 videos
31 files
994 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Сотрудничество, реклама: @devmangx

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
using var client = new HttpClient(); внутри цикла выглядит как ответственное управление ресурсами. На деле это утечка сокетов.

Каждый новый экземпляр HttpClient создаёт собственный пул соединений, а после вызова Dispose сокеты остаются в состоянии TIME_WAIT примерно на четыре минуты. Под нагрузкой доступные порты заканчиваются, и вы получаете SocketException, хотя сервер полностью исправен.

Вместо этого внедрите IHttpClientFactory. Одна строка — и проблема решена.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍4🍾2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🍾1
Большинство senior-разработчиков советуют создавать репозитории для EF Core.

Но это не лучший подход к написанию кода.

По мере роста .NET-проектов работа с данными становится всё сложнее.

Многие команды начинают с паттерна Repository, оборачивая в него запросы EF Core.

Поначалу это работает нормально. Но по мере роста проекта репозитории либо делают недостаточно, либо пытаются делать слишком много.

Когда бизнес-требования меняются, код становится сложнее понимать и модифицировать.

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

Помните, что DbContext в EF Core уже реализует паттерны Repository и Unit of Work.

Это прямо указано в официальной документации Microsoft по DbContext. То же самое можно увидеть в описании класса DbContext в вашей IDE.

Создавая репозиторий поверх EF Core, мы создаём абстракцию над абстракцией, что приводит к чрезмерно усложнённым решениям.

Как решить эту проблему? Ответ — паттерн 𝗦𝗽𝗲𝗰𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻.

Паттерн Specification — это способ описать, какие данные вы хотите получить из базы данных, с помощью небольших переиспользуемых классов, называемых спецификациями.

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👎41🍾1
Файловые приложения поддерживают ссылки на .dll через #:include.
Начиная с .NET 11 Preview 6

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍3🥰1🍾1
Не начинайте с микросервисов.

Даже если вы уверены, что ваше приложение вырастет настолько, что такой подход будет оправдан.

И вот почему.

У микросервисов есть своя цена:

* Координация между командами
* Работа со сбоями
* Eventual consistency
* Автоматизация деплоя
* Управление несколькими сервисами
* Развёртывание дополнительной инфраструктуры

В начале нового проекта эта сложность вам не нужна.

Даёт ли она ценность пользователям? Скорее всего, нет.

Опыт вашей команды играет значительную роль.

Если вы не умеете управлять большим монолитом, с микросервисами лучше не станет.

Определение границ сервисов требует большой работы. Насколько вы уверены, что сможете правильно провести их с самого начала?

Если вы ошибётесь, рефакторинг границ сервисов будет сложным. В монолите это сделать гораздо проще.

Вот менее рискованная стратегия:

* Начните с монолита
* Определите границы сервисов — bounded contexts
* Затем решите, действительно ли их нужно выделять в микросервисы

Есть и множество других факторов. Все их невозможно уместить в одном посте.

Но надеюсь, я дал вам пищу для размышлений.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Microsoft подтвердила «значительное ускорение» поиска по разделу «Этот компьютер» в Проводнике Windows 11.

Маркус Эш, руководитель направления дизайна и исследований Windows, подтвердил, что улучшения скорости и релевантности, которые Microsoft внедряет в Windows Search, следующим этапом появятся в Проводнике. В первую очередь речь идёт о «значительном ускорении» поиска по всему разделу «Этот компьютер».

Это важно, потому что сейчас поиск по разделу «Этот компьютер» работает мучительно медленно.

Я протестировал поиск одного и того же файла через Windows Search и Проводник. Windows Search нашёл его примерно за секунду.

Поиск в Проводнике по всему разделу «Этот компьютер» занял более 8 минут.

И это был не перегруженный компьютер с тысячами файлов. Это был практически чистый тестовый ПК, на который почти ничего не было загружено.

Windows Search уже стал заметно лучше: более чистый интерфейс, меньше отвлекающих элементов, приоритет локальных результатов, обработка опечаток, поиск файлов по двум символам, поиск по подстроке и переключатель для отключения рекомендаций Bing и Microsoft Store.

Теперь эти улучшения поиска файлов наконец появятся и в Проводнике...

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯8🥴4😁3🍾1
Совет по Minimal API 💡

Как сделать обработчик чище?

Minimal API — это новый и лаконичный способ создавать REST API в .NET.

Один endpoint состоит из:

* extension-метода, соответствующего HTTP-методу
* маршрута
* обработчика

Обработчики часто пишут прямо в теле endpoint, но такой подход подходит только для простых случаев.

Что делать, когда код разрастается и становится перегруженным?

Использовать локальные функции.

Они позволяют вынести логику внутрь отдельного метода и передать его как обработчик.

В результате endpoints становятся чище, а логика оказывается инкапсулирована в одном месте.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6🤔1🏆1🍾1
Я часто слышу, что C# — мусор и что с ним не стоит работать.

Вот почему, на мой взгляд, он лучше, чем считают некоторые:
В backend-разработке и CPU-intensive сценариях C# может быть значительно быстрее интерпретируемых языков и языков с динамической типизацией.

C# превосходит Python по скорости. Python-код обычно выполняется построчно во время работы программы, тогда как C# заранее компилируется, а затем дополнительно оптимизируется во время выполнения. У него очень эффективный runtime.
В CPU-intensive задачах и высоконагруженных backend-системах C# часто превосходит JavaScript и Node.js.

По производительности C# и Java обычно идут примерно на одном уровне.
Сравнение C# и Go неоднозначно. Go отлично подходит для сервисов, но C# предлагает более богатую экосистему, более продвинутые оптимизации runtime и мощные возможности языка.

C++ и Rust обычно быстрее C#, когда в приоритете максимальная производительность и полный контроль над памятью.

Но это лишь часть картины.

Что предлагает C#:
Производительность
Продуктивность разработчика
Строгая типизация
Поддерживаемость кода
Безопасная работа с памятью
Зрелая экосистема

JIT-компиляция оптимизирует участки кода, которые выполняются чаще всего.
Предварительная компиляция позволяет сократить время запуска и потребление памяти.
Сборщик мусора эффективно работает в приложениях с высокой пропускной способностью.
Разработчики могут использовать API вроде Span<T> и pipelines, чтобы уменьшать количество аллокаций и работать ближе к памяти.

Также C# позволяет создавать масштабируемые приложения, способные обрабатывать тысячи одновременных I/O-операций с помощью async и await.

Наконец, C# подходит для разработки самых разных типов приложений:
> ASP.NET Core — для Web API и backend-систем
> облачные сервисы и распределённые приложения
> WPF, WinUI и .NET MAUI — для desktop-приложений
> кроссплатформенные мобильные приложения
> игры на Unity
> background workers, планировщики и системы автоматизации
> AI-приложения и обработка данных с ML.NET

На C# также можно создавать serverless-функции, IoT-решения, CLI-инструменты, приложения реального времени и высокопроизводительные сетевые сервисы.

C# не всегда оказывается самым быстрым языком в каждом бенчмарке.
Но для многих реальных приложений он предлагает одно из лучших сочетаний производительности, продуктивности, инструментов и зрелости экосистемы.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍212🍾2
Поддержка .NET 8 заканчивается через четыре месяца

10 ноября 2026 года Microsoft прекратит поддержку .NET 8, поэтому уже сейчас стоит планировать переход на .NET 10.
.NET 10 относится к LTS-релизам и будет получать обновления до 14 ноября 2028 года.

Одно из главных изменений — заметный прирост производительности ASP.NET Core. По сравнению с .NET 8 он способен обрабатывать на 15% больше запросов в секунду. Для Minimal APIs потребление памяти также снизилось на 93%, что значительно уменьшает общий working set приложения.

Что нового появилось в .NET 10:

C# 14
В язык добавили extension members, присваивание через null-conditional оператор, ключевое слово field, модификаторы параметров в лямбда-выражениях, а также partial-конструкторы и события.

Файловые приложения
Теперь небольшой C#-код можно запускать прямо из одного файла .cs, без создания .sln и .csproj.

ASP.NET Core
Minimal APIs получили встроенную валидацию и поддержку JSON Patch. Также появились Server-Sent Events и поддержка OpenAPI 3.1.

EF Core
Добавлены опциональные complex types, поддержка JSON и структур, операторы LeftJoin и RightJoin, именованные query-фильтры и расширенные возможности ExecuteUpdate.

.NET Aspire
В Aspire 9.5 появился отдельный CLI, поддержка файлового AppHost, визуализатор генеративного ИИ, улучшенная трассировка, интеграция с хостингом OpenAI и поддержка эмуляторов Azure.

Blazor
Для Blazor WebAssembly добавили Hot Reload, настройку окружения, профилирование производительности и диагностические счётчики. Также улучшили роутинг, предварительную загрузку статических ресурсов и валидацию форм.

Библиотеки и Runtime
Появились новые API для криптографии, сериализации, коллекций, диагностики, числовых операций и работы с ZIP-файлами. Runtime получил улучшения JIT, NativeAOT, девиртуализации методов, стековых аллокаций и генерации кода, а также поддержку AVX10.2.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
2🍾1
Большинство разработчиков неправильно подходят к оптимизации SQL-запросов

Часто разработчики часами переставляют условия в WHERE, переписывают IN на EXISTS или добавляют query hints. Но в большинстве случаев это почти не влияет на производительность.

Современные СУБД и так умеют самостоятельно менять порядок JOIN и применять фильтры как можно раньше. Поэтому важнее не то, как именно записан запрос, а может ли база эффективно использовать индексы и правильно оценить объём данных.

Основной прирост скорости обычно дают три вещи.

Во-первых, фильтры должны позволять использовать индекс.
Например, если применить функцию к индексируемому столбцу:
EXTRACT(YEAR FROM order_date) = 2025
база может отказаться от использования индекса. Гораздо эффективнее задать диапазон по самому столбцу с датой.

Во-вторых, нужно правильно подбирать индексы.
В первую очередь стоит индексировать столбцы, которые участвуют в WHERE, JOIN и ORDER BY. При этом один составной индекс, например (status, order_date), часто работает лучше двух отдельных.

В-третьих, статистика таблиц должна быть актуальной.
Планировщик выбирает план выполнения на основе статистики. Если она устарела, база может выбрать неудачный план даже при хороших индексах.

Поэтому важнее правильно настроить индексы и статистику, чем бесконечно переписывать сам запрос.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1👏1🍾1
Чувак рассказывает, как провалил техническое интервью из-за оптимизации одного отчётного запроса.
На маленьком объёме данных всё выглядело нормально: запрос выполнялся быстро. Но на тестовой базе с 500 000 строк он внезапно стал очень медленным.

Причина — скрытая проблема N+1: внутри SELECT был подзапрос, который выполнялся заново для каждой строки результата. То есть вместо одного обращения к базе происходили сотни тысяч повторных операций.

Решение оказалось простым — заменить такие подзапросы на JOIN, чтобы база могла обработать данные одним проходом.

Ещё одна частая ошибка — несколько одинаковых подзапросов для расчёта разных метрик. Например, отдельно считать сумму покупок клиента и количество заказов. Вместо этого лучше один раз собрать агрегированные данные через CTE, а потом присоединить результат.

Главный вывод: SQL, который летает на сотне строк, может полностью сломаться на больших данных. Оптимизацию нужно проверять не только на локальных тестах, но и на реальных объёмах.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣6👍4🤯1🍾1
В .NET долгое время одним из самых удобных инструментов для организации CQRS и разделения логики был MediatR, он помогал структурировать команды и запросы, разгружал API слой и снижал связанность кода. Многие проекты, особенно с архитектурой Vertical Slice, держались на нём годами.

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

Альтернатива, которая решает эти проблемы, — переход на простые ручные обработчики. Такой подход убирает лишнюю рефлексию и декораторы, упрощает трассировку, а IDE быстрее находит нужный участок кода.

Вот гайд как выстроить систему, где:

> Стартовая реализация использует MediatR, а затем заменяется на ручные обработчики

> Регистрация обработчиков происходит автоматически

> Уведомления обрабатываются без MediatR Notifications

> Общая функциональность (логирование, валидация, транзакции) подключается без лишней обвязки

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
5🤨1🍾1
В C# 16 разработчики планируют сосредоточиться на нескольких крупных направлениях:

Среди них — развитие unsafe, новый синтаксис для словарей, закрытые enum, улучшенный вывод типов и более удобное декларативное создание интерфейсов.

https://github.com/dotnet/csharplang/discussions/10276/

Как вам такой набор изменений?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾4🌭2
Сегодня у меня для вас небольшая задачка.

Оба метода удаляют один товар и возвращают одинаковые HTTP-статусы, но…

Под капотом они работают совершенно по-разному.

Какую реализацию выбрали бы вы?

Сможете определить различия?

Пишите свои варианты решения в комментариях!

Приятного брейншторма! 🧠

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾21
Строки в C# кажутся простой темой — пока не становятся причиной:

нечитаемого кода
лишних аллокаций
скрытых ошибок при сравнении
некорректной валидации
неудобного форматирования многострочного текста

В своих проектах я придерживаюсь пяти правил:
1. Использую интерполяцию строк
2. Для большого количества конкатенаций применяю StringBuilder
3. Проверяю строки через string.IsNullOrWhiteSpace
4. Явно указываю StringComparison
5. Использую raw- или verbatim-строки

Меньше экранирования.
Меньше лишнего шума.
Более читаемый код.
Даже небольшие улучшения в работе со строками делают код безопаснее, чище и проще в поддержке.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4🍌1😐1🍾1
Паттерн Saga — одна из базовых вещей, которую стоит понимать при работе с распределёнными системами.

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

Обычно Saga строится одним из двух способов:

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

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

И здесь нет универсального ответа — решение зависит от логики конкретного бизнеса.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👌3🍾1
Вот 8 простых приёмов, которые делают код чище:

Используйте result objects
Объединяйте if, когда условия можно выразить вместе
Применяйте early return
Заменяйте magic strings на enum
Предпочитайте собственные исключения
Используйте LINQ, когда он делает код короче и понятнее
Заменяйте magic numbers на константы
Выносите сложные булевы выражения в отдельные методы

Хороший разработчик часто замечает code smells с первого взгляда.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
5🍾2
Команде .NET стоит внимательнее относиться к документации, потому что многие воспринимают примеры из неё как рекомендуемые практики.

Вот антипример: не стоит добавлять к IEnumerable индексатор, который внутри вызывает ElementAt.

От индексатора обычно ожидают стоимость доступа O(1).

доки

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾3
Как обычно рисуют архитектурные диаграммы?

Самый распространённый вариант — UML-диаграммы.
Но есть и другой подход — модель C4.

C4 расшифровывается как:
Context Diagram — диаграмма контекста системы
Container Diagram — диаграмма контейнеров
Component Diagram — диаграмма компонентов
Code Diagram — диаграмма кода

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🍾1
Windows 11 26H2: что нового этой осенью

Осенью Microsoft выпустит обновление Windows 11 26H2, которое принесёт множество улучшений во всей операционной системе.

Среди изменений — доработки меню «Пуск», изменения панели задач, более глубокие обновления поиска, улучшения Проводника и новые инструменты для повышения удобства работы.

Похоже, это будет один из самых интересных релизов Windows за последние годы.

Вот всё, что известно на данный момент

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣51🔥1🍾1
Если тебе кажется, что для результатов true/false есть только if/else
…то вот альтернатива.

Тернарный оператор — это условный оператор в C#, который во многих случаях работает как компактная версия if/else.

Для него нужны три части:
- условие;
- результат, если условие истинно;
- результат, если условие ложно.

Если условие возвращает true, используется первое значение. Если false — второе.
Тернарный оператор поддерживает target-typing и может использоваться с var.

При этом типы результатов должны быть совместимы: один тип должен неявно приводиться к другому либо оба значения должны приводиться к целевому типу.

Тернарный оператор помогает сократить несколько строк кода до одной.
Но если условий становится много, код быстро становится запутанным и хуже читается.
Так что держи в голове: тернарный оператор — хорошая альтернатива для простых if/else.
Для более сложной логики лучше использовать switch expression.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣10😁3🤯2🍾2👏1