C# Portal | Программирование
15K subscribers
755 photos
86 videos
19 files
666 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Связь: @devmangx

РКН: https://clck.ru/3FocB6
Download Telegram
До сих пор часто вижу такой паттерн:

if (items.Count() > 0)
{
// ...
}


Это неэффективно.

Почему?

🔸Count() проходит по всей коллекции или делает COUNT(*) в базе данных.
🔸Если тебе просто нужно проверить, есть ли элементы — используй Any().

Any() останавливается на первом найденном элементе.
В SQL это переводится в EXISTS, что значительно легче, чем COUNT(*).

Основные выводы:

🔸Используй Any() для проверки на наличие элементов.
🔸Используй Count() только если реально нужен точный размер коллекции.

Такие небольшие оптимизации имеют значение особенно когда приложение растёт и работает с большими объёмами данных.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍253
Горячее мнение:
ВАМ НЕ НУЖНЫ библиотеки для маппинга.


🔸Напиши конструктор
🔸Вызови конструктор
🔸Готово

Это может быть и статический метод, или что тебе больше нравится.

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

И ещё реже какие-либо библиотеки для маппинга.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🤔32
.NET Aspire теперь поддерживает создание баз данных MySQL

И настройка занимает всего одну строку

С момента релиза в статусе General Availability, .NET Aspire изменил подход к созданию облачных приложений на .NET.

Менее чем в 30 строках кода вы можете настроить:

- API
- Базы данных
- Кэш

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

Что лично для меня круто — возможность добавить и создать целую базу данных одним методом.

Метод AddDatabase выполняет SQL-команду CREATE DATABASE с заданным именем на работающем контейнере или сервере.

Ранее эта функция поддерживала:

- SQL Server
- PostgreSQL

Но теперь, начиная с версии 9.3, добавлена поддержка MySQL.

Вам не нужно ничего дополнительно делать — ваш существующий вызов AddDatabase теперь автоматически создаёт базу данных.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
9😁2
Пример Task.WhenEach в .NET 9

В .NET 9 появилась новая API — Task.WhenEach, которая позволяет обрабатывать асинхронные задачи по мере их завершения.

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

Ты уже пробовал эту новую фичу? 🔥

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥28👍84
Перестань совершать ЭТУ критическую ошибку при запуске нового software проекта:

Пытаться выстроить идеальную архитектуру с первого дня.

Мой главный инсайт про архитектуру ПО?

«Хорошая архитектура не статична. Она развивается.»


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

В этом и суть эволюционной архитектуры:

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


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

🔸Evolutionary Architecture

→ Один проект на GitHub, в котором показано, как начать с простой .NET-архитектуры, а затем эволюционно перейти к модульному монолиту и микросервисам по мере роста требований и кодовой базы.
→ Ссылка: https://github.com/evolutionary-architecture/evolutionary-architecture-by-example

🔸Booking to Cloud Architecture

→ Приложение для бронирования, реализованное тремя способами: монолит, модульный монолит и микросервисы.
→ Монолит: https://github.com/meysamhadeli/booking-monolith
→ Модульный монолит: https://github.com/meysamhadeli/booking-modular-monolith
→ Микросервисы: https://github.com/meysamhadeli/booking-microservices

Когда ты перестаёшь воспринимать архитектуру как то, что нужно «угадать» с первого дня, ты даёшь себе право на ошибку.

Право учиться.
Право адаптироваться.
И расти вместе с системой.

Потому что хорошая архитектура рождается не из предсказаний будущего —
она рождается из эволюции в будущем.


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥82
10 скрытых фич EF Core, которые используют сеньоры

1️⃣Shadow Properties
EF Core позволяет добавлять свойства, которых нет в классе, но которые присутствуют в базе данных.
Идеально подходят, например, для хранения данных аудита, не засоряя сущности лишними полями.

2️⃣Query Tags
Можно легко добавлять комментарии к SQL-запросам, которые генерирует EF Core.
Удобно при профилировании - в логах SQL сразу видно, откуда пришёл тот или иной медленный запрос.

3️⃣Compiled Queries
Часто используемые запросы можно скомпилировать заранее, чтобы не тратить ресурсы на парсинг каждый раз.
Повышает производительность при большом числе однотипных запросов.

4️⃣DbContext Pooling
Вместо того чтобы каждый раз создавать новый DbContext, можно переиспользовать уже созданные.
Существенно снижает потребление памяти и повышает производительность.

5️⃣Value Converters
Позволяют автоматически преобразовывать значения между .NET и базой данных.
Полезно для хранения кастомных типов, enum'ов и Value Object'ов.

6️⃣Temporal Tables
Позволяют отслеживать историю изменений данных прямо в базе.
Удобно для аудита, отката изменений и анализа исторических данных.

7️⃣Database Seeding
EF Core 9 добавил новые методы UseSeeding, UseAsyncSeeding для удобного наполнения базы начальными данными.

8️⃣Split Queries for Includes
Позволяет разбивать сложные запросы с Include на несколько простых.
Избегает проблем с громоздкими JOIN’ами и повышает производительность.

9️⃣Raw SQL Queries
Можно выполнять чистый SQL прямо из EF Core.
Полезно, когда нужно выжать максимум производительности или использовать специфичный функционал конкретной СУБД.

1️⃣0️⃣Миграции для нескольких баз данных
Можно легко управлять миграциями и схемами сразу для разных провайдеров.
Подходит для приложений, которые должны работать с несколькими СУБД (например, SQL Server, PostgreSQL, MySQL).

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Proxy Design Pattern

Что такое паттерн Proxy?

Proxy предоставляет объект-заместитель, который контролирует доступ к другому объекту.
Это как пользоваться банковской картой вместо наличных — те же возможности, но с большим контролем.

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

🔸Когда стоит использовать

Используйте Proxy, когда нужно:

- реализовать ленивую инициализацию тяжёлых объектов;
- контролировать доступ к объекту (например, авторизация);
- логировать входящие запросы;
- кэшировать результаты;
- управлять удалёнными ресурсами (например, через сеть).

Proxy идеально подходит, когда нужно добавить поведение к объекту, не изменяя его исходный код — например, добавить проверки безопасности или метрики производительности.

🔸Как реализовать

1. Создайте класс Proxy, реализующий тот же интерфейс, что и основной сервис.
2. Proxy хранит ссылку на реальный объект и перехватывает все обращения к нему.
3. В зависимости от логики, прокси может:
- разрешить/запретить доступ;
- отложить создание объекта;
- закэшировать результат;
- добавить побочные эффекты (лог, метрики и т.д.).


🔸Распространённые типы Proxy:

- Virtual Proxy — отложенное создание объекта;
- Protection Proxy — контроль прав доступа;
- Remote Proxy — работа с удалёнными объектами;
- Caching Proxy — кэширование результатов вызова.

> Proxy может выполнять свои действия до или после делегирования запроса реальному объекту.

🔸Почему это работает

- клиент работает с Proxy, не зная о реальной реализации сервиса.
- Proxy продолжает работать даже если объект-сервис ещё не создан или временно недоступен.
- можно добавлять новые прокси, не меняя код клиента или сервиса.

🔸Недостатки

- Возможны задержки в ответах из-за дополнительной логики.
- Увеличивается сложность кода — появляются дополнительные классы и уровни абстракции.
- Непродуманная реализация Proxy может стать узким местом и источником багов (например, в многопоточности).

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥3
Секретная фишка в C#, о которой никто не знает

Она позволяет создавать высокопроизводительные .NET-приложения.

Разработка надёжных, масштабируемых и быстрых .NET-приложений во многом зависит от того, как вы организуете конкуренцию и обработку данных.

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

Ранее для этого использовали такие конструкции, как Queue<T>, ConcurrentQueue<T> или BlockingCollection<T>.

Эти очереди оборачивали в классы и применяли для управления потоками данных.

Однако у таких решений есть существенный минус — сильная связанность кода. 💊

Channels в C# это малоизвестная, но мощная фишка, которая предлагает современный способ построения безопасных, асинхронных и высоконагруженных .NET-приложений.

Они реализуют паттерн "производитель-потребитель": один класс создаёт данные, другой их потребляет - при этом оба ничего не знают друг о друге.

Ключевым архитектурным моментом при работе с каналами является выбор между ограниченными и неограниченными каналами.

Вот гайд, где узнаете:

➡️ Что такое C# Channels?
➡️ Ограниченные vs. неограниченные каналы
➡️ Фоновая обработка через Channels
➡️ Применение каналов в боевом ASP.NET Core-приложении
➡️ Лучшие практики и советы по работе с Channels

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥64😁1
В модульной монолитной архитектуре каждый модуль должен полноценно владеть своими данными. Для каждого модуля в PostgreSQL следует использовать отдельную схему и роль, а в EF Core — отдельный DbContext и строку подключения. Чтение данных между модулями должно выполняться через read model или представление , а не с помощью неконтролируемых join-ов

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥5🥴1😐1
Числовой StringComparer появится в dotnet 10

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
14🔥10
LINQ-метод Shuffle() появится в .NET 10

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

LINQ уже включает API для изменения порядка элементов, такие как OrderBy() и Reverse().
Однако на данный момент нет стандартного API для перемешивания IEnumerable<T>.

(Существует System.Random.Shuffle() для Span<T>, но если нужно перемешать произвольную последовательность IEnumerable<T>, скорее всего, придётся писать собственную реализацию.)

На StackOverflow часто можно встретить примеры перемешивания с использованием кода вроде .OrderBy(_ => Guid.NewGuid()).
Однако такой подход неэффективен, и есть более оптимальные способы перемешивания.

Поэтому предлагается реализовать System.Linq.Shuffle().

🔸API Proposal — Предложение API

namespace System.Linq
{
public static class Enumerable
{
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source) { }
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random randomSource) { }
}
}


🔸API Usage — Пример использования

var songs = ["Lorem", "ipsum", "dolor", "sit", "amet"];
foreach (var song in songs.Shuffle())
{
Play(song);
}

// выбрать 3 уникальные песни
var threeSongs = songs.Shuffle().Take(3).ToArray();


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
12
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23😁193
Рендеринг шаблона в PDF с помощью PuppeteerSharp:

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍3🤔1
Первичные конструкторы в dotnet

ДО .NET 8 (Традиционный подход с конструктором):

public class UserService
{
private readonly HospitalDBContext _dbContext;
private readonly ILogger<UserService> _logger;
private readonly IEmailService _emailService;

public UserService(
HospitalDBContext dbContext,
ILogger<UserService> logger,
IEmailService emailService)
{
_dbContext = dbContext;
_logger = logger;
_emailService = emailService;
}

// Методы бизнес-логики здесь...
}


ПОСЛЕ .NET 8 (Использование Primary Constructor):

public class UserService(
HospitalDBContext _dbContext,
ILogger<UserService> _logger,
IEmailService _emailService)
{
// Методы бизнес-логики здесь...
}


Круто или нет?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19🤨76🐳2😁1
Не совершайте эту ошибку

Не используйте .ToLower() для сравнения строк. Почему?

Метод .ToLower() создаёт новую строку в памяти для каждого сравнения, что приводит к лишним аллокациям.

Представьте метод, который вызывается очень часто — это может деградировать производительность приложения.

Кроме того, .ToLower() чувствителен к культуре, то есть результат может различаться в зависимости от текущей культуры, установленной в исполняющем потоке.

Что использовать вместо этого?

В .NET есть мощное перечисление — StringComparison.

Возможные варианты StringComparison:

- Ordinal — используйте в большинстве случаев, когда культурные правила не важны. Самый быстрый вариант.
- OrdinalIgnoreCase — для сравнений без учёта регистра, где культурные правила не имеют значения.
- CurrentCulture и CurrentCultureIgnoreCase — используйте при сравнении строк, отображаемых пользователю, так как они учитывают культурные правила.
- InvariantCulture и InvariantCultureIgnoreCase — подходят, когда нужна единообразная логика вне зависимости от культуры, например, при сохранении и извлечении данных.

> EF Core выбросит исключение, если использовать методы вроде
> String.Equals(string, StringComparison), так как они не транслируются в SQL.

Это не будет работать с EF.
Если вы используете SQL Server с коллацией по умолчанию, сравнение строк уже нечувствительно к регистру, поэтому обычное a == b или string.Equals(a, b) в LINQ будет работать.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍313
Посмотрите этот классный open-source инструмент для визуализации JSON-данных в интерактивных графах.

Он предлагает функции конвертации JSON в другие форматы (CSV, YAML), генерацию JSON Schema, выполнение запросов и экспорт визуализаций в виде изображений.

Также он умеет форматировать, валидировать и создавать интерфейсы TypeScript.

Репозиторий: https://github.com/AykutSarac/jsoncrack.com

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍138🥴2
Что нового в C# 14

Главные апдейты

Extension members теперь можно расширять не только методами но и свойствами и индексаторами плюс есть статические расширения для самого типа.

field как контекстный токен для простых автосвойств с логикой сеттера без явного бэкинг филда.

Условный доступ слева от присваивания то есть ?. и ?[] можно ставить перед тем что присваиваешь удобно и безопасно.

nameof понимает «пустой» дженерик тип например nameof(List<>).

Модификаторы у параметров простых лямбд ref, in, out, scoped теперь можно без явного типа.

Больше не мучаемся со Span<T> и ReadOnlySpan<T> стало больше неявных конверсий и это лучше дружит с инференсом и экстеншенами.

Больше partial теперь можно частично объявлять конструкторы и события.

Пользовательские составные операторы присваивания то есть можно задавать свою семантику для вроде +=.

Пара мини примеров

field в действии

public class Box
{
public string Title
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
}


Условное присваивание

customer?.Order = FetchOrder();
bag?["count"] += 1;


nameof с незаполненным дженериком

var n = nameof(List<>); // "List"


Модификатор у лямбды без явных типов

delegate void Bump(ref int x);
Bump inc = (ref x) => x++;


Как попробовать


Ставишь свежий .NET 10 SDK и актуальный Visual Studio 2022 эти фичи уже в превью ветки для десятки. Страница с новыми фичами обновлялась под .NET 10 Preview 1 в апреле 2025.

🔸подробнее - https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
14😁1
Лучший урок по C# за сегодня

(чтобы срезать количество багов примерно на 50%)

Не возвращайте из методов null для коллекций

Возвращайте пустые коллекции

STOP:
- Заставлять вызывающий код проверять null
- Захламлять код лишними условиями
- Рисковать трудноотлавливаемыми runtime-исключениями

Начните:
- Возвращать new List<T>()
- Возвращать Enumerable.Empty<T>()
- Возвращать [] (фича C# 12 — collection expression)

Так пишется безопасный, чистый и читаемый код

Пусть остальные продолжают тонуть в проверках на null 👍

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🕊75🐳1
Джуниор должен знать 4 паттерна

Мидл — уже 12

Сеньор — около 20


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

Задумывался, на какие паттерны стоит делать упор, когда растешь как разработчик? 🌟

Это реально разница между «писать неплохой код» и «строить крутое ПО»

🔸Джуниор

Тебе не нужно сразу выучить всё.
Сконцентрируйся на базовых паттернах, которые встречаются повсюду

> Builder
> Factory Method
> Singleton
> Decorator

Эти четыре паттерна помогут эффективно создавать, организовывать и расширять объекты.
Освоишь их — с первого дня начнешь писать чище и гибче

🔸Мидл

Готов прокачаться дальше

Пора добавить в свой арсенал более универсальные инструменты

> Strategy
> Adapter
> Abstract Factory
> Template Method
> Facade
> Bridge
> Command
> Mediator

Они научат подменять поведение на лету, упрощать сложные системы и писать более модульный код

🔸Сеньор

Базу ты уже знаешь.
Теперь можно разбираться с паттернами, которые решают самые жёсткие архитектурные задачи

> Prototype
> Composite
> Chain of Responsibility
> State
> Flyweight
> Proxy
> Visitor
> Interpreter

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

Не пытайся выучить всё за раз

Иди по порядку — сначала базу, потом средний уровень, потом продвинутые паттерны

Кстати, а у тебя какой паттерн дольше всего не заходил, и как ты в итоге его понял? 👀

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤨1513👍6😁2🤣1
Паттерн Options в .NET — это одна из тех фич, которые я стабильно использую во всех своих C#-проектах

Более чистое управление конфигами
Сильно типизированные классы
Простая интеграция с DI
Без проблем работает с appsettings.json, secrets.json, Azure Key Vault и прочим

Почему это важно

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

Обычно это выглядит так

🔹Определяешь конфиг в appsettings.json
🔹Создаёшь POCO-класс
🔹Биндишь его через .AddOptions<T>().BindConfiguration()
🔹Инжектишь в сервисы через IOptions<T>

Просто. Масштабируемо. Аккуратно.

А ты используешь этот паттерн у себя или до сих пор дёргаешь значения конфигов через IConfiguration["key"] 😃

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
26👍6🍓3👨‍💻1