C# Portal | Программирование
13.9K subscribers
1.15K photos
126 videos
29 files
931 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

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

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Поток выполнения запроса Entity Framework ⬇️
Please open Telegram to view this post
VIEW IN TELEGRAM
9👌4
Все еще сидишь на .sln в 2026?

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

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyApp", "MyApp\MyApp.csproj", "{8A3B4E29-7F7D-4C51-9A18-5D8B9A3E1234}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

.... +200 more unreadable lines?


🤮Везде GUID’ы, вечные merge-конфликты, читать невозможно.

А теперь то же самое в .slnx:

<Solution>
<Project Path="MyApp/MyApp.csproj" />
</Solution>


Вот и всё. Читаемо человеком, дружит с git, никаких GUID’ов.

Почему стоит мигрировать сейчас:

▪️Поддерживается в Visual Studio 2022 (17.10+) и .NET 9+
▪️dotnet sln migrate делает это одной командой
▪️Меньше merge-конфликтов, меньше боли в команде
▪️В code review это наконец можно нормально читать

Как мигрировать:

dotnet sln migrate MyApp.sln


Готово. .slnx создан.

Старый формат делали под внутренности Visual Studio, не под людей. SLNX делают для разработчиков.

Все еще держишься за .sln? Почему?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍284🔥1
Это markdown-док с практическими рекомендациями по асинхронщине в .NET и типичным граблям, особенно в вебе на ASP.NET Core: читать

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍84
Используй [] вместо Array.Empty в corelib ⬇️
Please open Telegram to view this post
VIEW IN TELEGRAM
13😐9👎1
Знаешь, что даже простая смена C# langversion может повлиять на производительность?

В C# 11 поменялась генерация кода для конверсии method group так, чтобы в некоторых случаях избегать аллокаций.

Пример:

[Benchmark]
public int Lambda()
{
Func<int> func = () => Method();
return func();
}

[Benchmark]
public int MethodGroup()
{
Func<int> func = Method;
return func();
}

static int Method() => 42;


на net4.8 при LangVersion C# 10 и ниже вариант с method group может создавать делегат (то есть аллоцировать) и из-за этого быть заметно медленнее. А при LangVersion C# 11+ компилятор меняет генерацию кода так, чтобы делегат кэшировался, и аллокации пропадают.

В C# 11 поменяли codegen, чтобы кэшировать конверсию method group

C# 10 и ниже (делегат создается на месте):

return new Func<int>((object)null, __methodptr(Method))();


C# 11 и выше (делегат кэшируется):

return (MethodGroupBenchmarks.<>O.<0>__Method ??
(MethodGroupBenchmarks.<>O.<0>__Method = new Func<int>((object)null, __methodptr(Method))))();


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔8
В .NET 10 больше не нужно писать Dockerfile.
Кто уже пользуется новой фичей? Как ощущения в проде?

Типичный многостадийный Dockerfile для .NET-приложения выглядит примерно так:

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["src/MyApi/MyApi.csproj", "src/MyApi/"]
RUN dotnet restore "src/MyApi/MyApi.csproj"

COPY . .
WORKDIR "/src/src/MyApi"
RUN dotnet build "MyApi.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "MyApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyApi.dll"]


Это работает, но есть кривая обучения и накладные расходы на поддержку:

Поддержка: нужно вручную обновлять теги базовых образов
Кэширование слоёв: неправильный порядок COPY убивает кэш сборки
Дублирование: почти каждому проекту нужен похожий Dockerfile
Переключение контекста: ты пишешь Docker DSL, а не .NET-код

Подход с .NET SDK устраняет все эти проблемы.

Если ты работаешь на .NET 10, ничего дополнительно включать не нужно. Публикация в контейнеры работает из коробки для ASP.NET Core-приложений, worker-сервисов и консольных приложений.

Можно сразу публиковать приложение в контейнерный образ:

dotnet publish --os linux --arch x64 /t:PublishContainer


И всё. .NET SDK сам:

соберёт приложение
подберёт подходящий базовый образ
создаст контейнерный образ с результатом публикации
загрузит его в локальный OCI-совместимый демон

Чаще всего это Docker, но Podman тоже поддерживается.

(На скрине показан вывод команды dotnet publish, создающей контейнерный образ.)

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥146
This media is not supported in your browser
VIEW IN TELEGRAM
AviyalWM: портативный и лёгкий оконный менеджер, написанный на C#

Рад сообщить о релизе AviyalWM — простого, лёгкого и портативного динамического тайлингового оконного менеджера для Windows. Краткий список возможностей:

▪️Рабочие пространства
▪️Анимации рабочих пространств (горизонтальные и вертикальные)
▪️Макеты: Dwindle, Stack, Master
▪️Переключение в плавающий режим
▪️Закрытие окна в фокусе
▪️Переключение фокуса
▪️Конфигурация через JSON
▪️Горячая перезагрузка
▪️Запрос состояния через WebSocket и выполнение команд
▪️Запуск приложений с помощью горячих клавиш

Репозиторий: https://github.com/TheAjaykrishnanR/aviyal

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
12🔥2
В .NET теперь добавили DecompressionMethods.Zstandard для автоматической распаковки HTTP-ответов

Это изменение вчера влито в dotnet main и, судя по всему, будет доступно в .NET 11.

На втором фото есть таблица от Gemini с сравнением Gzip, Brotli и Zstandard по скорости и сжатию.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👏13🔥21
Расширение CSV/TSV Editor для Visual Studio

Mads из Microsoft только что выпустил это, и выглядит реально круто.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥62
Когда появился Docker, это была настоящая революция.

Теперь .NET Aspire меняет способ доставки ПО навсегда.

И многие разработчики до сих пор не осознают масштаб этого сдвига.

Docker решил хаос с окружениями

До Docker проблема «у меня работает» была ежедневной:
• Разные версии ОС
• Отсутствующие зависимости
• Сломанные окружения повсюду

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

Это действительно было революцией.

Но Docker не решил всё

Он пакует приложения, но связи между сервисами всё ещё настраиваются вручную:
• Всё ещё приходится управлять строками подключения
• Всё ещё самому настраивать наблюдаемость

И распределённые системы остаются сложными.

Здесь .NET Aspire меняет правила игры

Aspire — это слой оркестрации для современных приложений.

Что Aspire делает из коробки:
• Service discovery → никаких хардкодных URL или портов
• Injection конфигураций → базы данных и кеши подключаются автоматически
• Встроенная наблюдаемость → логи, метрики, трассировки, готово с первого дня
• Локальная оркестрация → запускаем всю систему одной командой
• Production-ready деплой → через Docker Compose
• Cloud-ready деплой → Azure или AWS

Вот сам гайд

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍6
Поддержка паролей для ZIP-архивов появится в .NET 11? 🙈

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🤯91🔥1
Вышел новый превью .NET для Microsoft Agent Framework! Обновлённые API, только асинхронные потоки и помощники AsAIAgent. Разбираем критические изменения, новые примеры с Durable Agents и ключевые обновления пакетов.

Подробнее: https://hubs.li/Q0410DQ-0

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3👍21🔥1
Я очень долго не знал, что в Swagger есть такая фича. Даже не задумывался о ней до недавнего времени.

Совет:

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
// подожди… он ЗАПОМИНАЕТ мой Bearer Token?!
// даже после полного обновления браузера…
c.EnablePersistAuthorization();

// на один клик меньше, на одно лишнее дёрганье мышью меньше
c.EnableTryItOutByDefault();
});
}


Если ты тоже об этом не знал, это вполне может сэкономить тебе немного времени!

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍244🤯2
Перестаньте использовать булевые параметры.

user.SetStatus(true)

Когда читаешь такой код, приходится останавливаться и думать.
Что значит true? Активен? Подтверждён? Удалён?

Это называется flag argument.
Он заставляет лезть в определение метода, чтобы понять намерение.

Решение: заменяйте размытые булевые значения явными методами.
Вместо SetStatus(true) используйте user.Activate().

Намерение очевидно.
Язык читается естественно.
Комментарии не нужны.

Код читают намного чаще, чем пишут.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍164👎1
Деплой и апгрейд сервисов это всегда риск. В этом посте разбираем, как этот риск снижать.

Диаграмма выше показывает самые частые подходы.

▪️Multi-Service Deployment

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

▪️Blue-Green Deployment

В blue-green деплое есть две одинаковые среды: одна staging (blue), другая production (green). Staging на одну версию впереди прода. Когда тесты в staging пройдены, пользовательский трафик переключается на staging, и staging становится продом. У этой стратегии простой rollback, но держать две одинаковые прод-качества среды может быть дорого.

▪️Canary Deployment

Canary-деплой обновляет сервисы постепенно, каждый раз только для части пользователей. Это дешевле, чем blue-green, и откатываться тоже удобно. Но так как staging-среды нет, тестировать приходится на проде. Процесс сложнее, потому что нужно мониторить canary и шаг за шагом переводить все больше пользователей со старой версии на новую.

▪️A/B Test

В A/B тесте разные версии сервисов одновременно крутятся в проде. Каждая версия проводит “эксперимент” на своей доле пользователей. Это дешевый способ проверять новые фичи в проде. При этом нужно жестко контролировать деплой, чтобы какие-то фичи случайно не уехали пользователям.

Твой ход: какую стратегию деплоя ты использовал? Были ли у тебя продовые инциденты из-за деплоя, и почему они случились?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥31
Что мне реально нравится в C#

Это не какая-то огромная или супер-впечатляющая фича, но мне заходит вот такое:

if (element is { Name: "tileset" })
{
...
}


Наверное потому что это близко к C и ассемблеру, поэтому такие штуки мне особенно кайфовые :-D

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

Трюк и самая сложная часть для разработчика это понимать, когда компилятор что-то оптимизирует, а когда нет. И без понимания, как эти штуки устроены, и без чтения release notes ты этого просто не узнаешь.

Раньше было так: переписал LINQ-запрос и почти всегда получал ускорение. Но в .NET 10 это уже не так, потому что теперь он оптимизирует и LINQ тоже.

Вообще на современном .NET 10 и актуальной версии C# стало как никогда просто писать код на C#, который по перформансу близок к C++, а иногда даже обгоняет его. Потому что теперь есть LibraryImport, и он может генерировать MSIL-интероп код без runtime marshalling...

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

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

GC это реально единственное, что мешает делать AAA 3D игры на C#.

Но даже это сейчас довольно управляемо благодаря stackalloc, Memory<T>, Span<T> и ref struct.

Пулы памяти тоже теперь есть: можно создавать объекты из пула и переиспользовать RAM, что отлично для GPU-сцен, где хочется минимум мусора и аллокаций.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
13
This media is not supported in your browser
VIEW IN TELEGRAM
Как можно использовать состояние при работе с MediatR?

Популярный nuget-пакет MediatR по умолчанию не делает хендлеры stateful. То есть при обработке сообщения каждый раз создается новый инстанс хендлера.

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

Например, что если тебе нужен кэш?

Самое простое решение: вынести ответственность за состояние в отдельный компонент. А дальше пусть dependency injection подсовывает этот компонент в хендлер.

Проблема решена ✌️

Полное видео тут

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🥴1
Git Tip: юзай команду git checkout -, чтобы быстро переключаться на предыдущую ветку, с которой ты только что работал.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🥴7😁2🔥1😐1