csharpproglib | Unsorted

Telegram-канал csharpproglib - Библиотека шарписта | C#, F#, .NET, ASP.NET

23284

Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Subscribe to a channel

Библиотека шарписта | C#, F#, .NET, ASP.NET

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#garbage_collector

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤖 AI-агенты в .NET MAUI

Контрибьют в .NET MAUI исторически требовал огромных затрат времени даже на простые баги: воспроизведение проблемы: 30–60 минут, поиск причины: 1–3 часа, реализация фикса ещё до двух часов, написание тестов ещё два. Итого 4–8 часов на один issue, и это у опытных разработчиков.

Команда Syncfusion опубликовала разбор того, как они встроили кастомных AI-агентов в процесс разработки.

Что построили

Набор специализированных агентов и переиспользуемых навыков, которые покрывают полный цикл:

pr-review skill — четырёхфазный процесс: анализ issue, проверка наличия тестов, до четырёх попыток фикса разными моделями, финальный отчёт с объяснением выбора лучшего подхода.

write-tests-agent — анализирует issue и выбирает нужный тип тестов: UI-тесты через Appium или XAML-тесты. Обязательно проверяет, что тест падает без фикса и проходит с ним.

sandbox-agent — ручная валидация в Sandbox-приложении. Для сценариев, которые трудно автоматизировать: визуальные баги, сложные жесты, поворот экрана.

learn-from-pr agent — анализирует смёрженные PR и улучшает инструкции и документацию. Система становится умнее после каждого цикла.

Для поиска фикса используются четыре модели последовательно — каждая предлагает независимый подход, тестирует его, записывает результат. После первого раунда модели видят чужие попытки и предлагают новые идеи. Одновременный доступ к одним файлам и одному устройству всё сломает.

➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#пульс_индустрии

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📎 ref vs out vs in

C# передаёт параметры по значению — метод получает копию, оригинал не меняется. Иногда это не то, что нужно.

ref — вы даёте, метод меняет, вы получаете обратно

Переменная должна быть инициализирована до вызова. Метод может изменить её — а может и не изменить, это не обязательно:

void Add(ref int total, int value) => total += value;

int sum = 0;
Add(ref sum, 5); // sum == 5
Add(ref sum, 3); // sum == 8


out — метод обязан заполнить

Переменную инициализировать не нужно. Но компилятор требует, чтобы метод присвоил значение до возврата, иначе ошибка компиляции. Именно поэтому весь паттерн Try* в стандартной библиотеке построен на out.

bool TryParse(string s, out int result)


in — только читать, не трогать


Передаёт по ссылке — без копирования. Но запрещает запись. Нужен исключительно для производительности с большими структурами. С классами смысла нет — они и так передаются по ссылке.

float Dot(in Vector3 a, in Vector3 b) => ...


📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👩‍💻 Открытый урок «Анатомия памяти: типы данных, способы хранения, аллокации и работа GC»

🗓 2 апреля в 20:00 МСК

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

На открытом уроке рассмотрим:
✔️ Рассмотрим фрагменты памяти, из которых состоит память .net-приложения, поговорим о том какие бывают типы;
✔️ Узнаем что из себя представляют процессы упаковки и распаковки;
✔️ Посмотрим на нюансы работы с управляемой кучей;
✔️ Разберем принципы работы сборки мусора.

🔗 Ссылка на регистрацию: https://clc.to/0Bt0-Q

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻 F#: `partitionWith` для разбивки коллекций на части с разными типами

Стандартная partition делит коллекцию на две части, но обе остаются одного типа. Если нужно одновременно отфильтровать и преобразовать элементы — приходилось делать два прохода или писать свою функцию.

partitionWith принимает функцию-разделитель с типом 'T -> Choice<'T1, 'T2> и возвращает два списка, которые могут иметь разные типы элементов:

val inline partitionWith:
partitioner: ('T -> Choice<'T1, 'T2>) -> list: 'T list -> 'T1 list * 'T2 list


Удобно то, что total active pattern (|A|B|) уже имеет сигнатуру 'T -> Choice<'T1, 'T2>, поэтому его можно передать напрямую:
let (|Valid|Invalid|) (s: string) =
match System.Int32.TryParse s with
| true, n -> Valid n
| _ -> Invalid s

let parsed, errors =
["42"; "hello"; "7"; "oops"; "99"]
|> List.partitionWith (|Valid|Invalid|)

// parsed = [42; 7; 99]
// errors = ["hello"; "oops"]


За один проход получаем распарсенные числа и строки с ошибками — каждая в своём типе.

Функция доступна для Array, List, Set и Array.Parallel.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👋 Сеньор занимается гейткипингом, а джун — на шадовинге

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

➡️ Изучайте словарь и больше не придётся гуглить в процессе разговора

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📎 Делегаты в горячем коде очень голодные

Одна аллокация делегата выглядит безобидно. Но если она происходит миллион раз за сессию, это уже проблема.

for (int i = 0; i < 100_000; i++)
{
queue.Enqueue(() => Process(i));
}


Здесь каждая итерация создаёт новый объект делегата и захватывает переменную i в замыкание. То есть рантайм выделяет память дважды на каждый шаг цикла.

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

Если делегат логически одинаков от вызова к вызову, то кешируйте его один раз:
private static readonly Action<Job> s_process = static job => Process(job);


static в лямбде явно запрещает захват внешних переменных. Если компилятор видит, что захват всё же происходит, он выдаст ошибку. Это хорошая защита от случайных замыканий.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

У «Библиотеки программиста» появился резервный канал в мессенджере MAX

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

Контент в MAX будет дублировать телеграмный — основной нашей площадкой был и остаётся Telegram. Надеемся, это временная мера.

Подписаться на «Библиотеку программиста» в MAX

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚙️ F#: кэширование разрешения перегрузок

Когда компилятор F# встречает вызов метода, он каждый раз заново проверяет все доступные перегрузки и выбирает подходящую. В файлах с тысячами однотипных вызовов это превращается в заметную часть времени компиляции.

Новая preview-фича кэширует результат этой проверки. Если метод вызывается повторно с теми же типами аргументов, компилятор берёт готовый результат из кэша вместо повторного перебора.

Ключ кэша состоит из трёх частей: идентификатор группы методов, типы аргументов и тип возвращаемого значения. Кэш автоматически отключается там, где контекст влияет на выбор перегрузки: именованные аргументы, SRTP-ограничения и похожие сценарии.

.NET 10 уже сам по себе ускорил компиляцию в шесть раз по сравнению с девяткой. Кэш перегрузок даёт ещё двукратный прирост сверху и заметно снижает давление на GC.

Фича доступна в preview. Чтобы включить, нужно добавить --langversion:preview в параметры компилятора.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤩 GitHub Copilot теперь умеет мигрировать .NET-проекты

Microsoft выпустила кастомный агент modernize-dotnet для GitHub Copilot. Раньше автоматизированная миграция .NET работала только внутри Visual Studio. Теперь тот же процесс доступен в VS Code, терминале через Copilot CLI и прямо на GitHub.

Агент работает по модели оценка → план → выполнение. На выходе — три артефакта прямо в репозитории: отчёт о текущем состоянии кода, план апгрейда с последовательностью шагов и набор задач с конкретными изменениями.

Как запустить в терминале:

/plugin marketplace add dotnet/modernize-dotnet
/plugin install modernize-dotnet@modernize-dotnet-plugins
/agent # выбрать modernize-dotnet
# затем: upgrade my solution to a new version of .NET


Поддерживаемые типы проектов: ASP.NET Core, Blazor, Azure Functions, WPF, консольные приложения и библиотеки. Миграция с .NET Framework тоже поддерживается — но только на Windows.

➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👀 Дайджест недели

Чуток материалов помимо второго превью .NET

.NET 11 Preview 2

Реферальный рекрутинг в IT

Протокол против AI слопа в вебе

MCP C# SDK v1.0

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🔄 Microsoft выпустила внеплановый патч .NET 10.0.5.

В .NET 10.0.4 сломался отладчик на macOS — при попытке дебажить любое .NET-приложение через VS Code он падал.

Кому стоит обновится: macOS + VS Code + .NET SDK 10.0.104 или 10.0.200 или рантайм 10.0.4.

Windows и Linux не затронуты.

➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

✏️ using — синтаксический сахар

Предлагаем ответить на вопрос с собеседования:

Что делает оператор using в C#


Почти каждый C#-разработчик писал такой код сотни раз:
using (var connection = new SqlConnection(connectionString))
{
// работаем с ресурсом
}


На первый взгляд — просто синтаксический сахар.

Подсказка: попробуйте мысленно развернуть этот блок в эквивалентный try/finally.

➡️ Проверить себя

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#dotnet_challenge

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

💡 Healthy ≠ Готов к работе

Большинство health check'ов проверяют три вещи:

- Запущен ли процесс?
- Есть ли коннект к базе данных?
- Доступен ли Redis?

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

Приложение может быть технически живым и при этом функционально сломанным. Процесс работает, эндпоинт возвращает 200, Kubernetes считает под здоровым, но первый же реальный запрос падает с ошибкой.

К примеру, кастомный health check для EF Core миграций:

public class DbContextMigrationsHealthCheck(DbContext dbContext) : IHealthCheck
{
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
try
{
var applied = await dbContext.Database
.GetAppliedMigrationsAsync(cancellationToken: cancellationToken);

var pending = await dbContext.Database
.GetPendingMigrationsAsync(cancellationToken);

if (pending.Any())
{
return HealthCheckResult.Degraded(
"Есть неприменённые миграции.",
data: new Dictionary<string, object>
{
{ "PendingMigrations", pending },
{ "LatestAppliedMigration", applied.LastOrDefault() ?? "" }
});
}

return HealthCheckResult.Healthy(
data: new Dictionary<string, object>
{
{ "LatestAppliedMigration", applied.LastOrDefault() ?? "" }
});
}
catch (Exception ex)
{
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}
}


Идея не ограничивается EF Core. Любая зависимость, которая доступна, но ещё не готова к работе:

• CMS — нужно прогреть кэш перед началом работы

• Биллинг — зависит от загрузки актуальных правил ценообразования

• Search API — ждёт готовности текущей версии индекса

Сервис здоров не тогда, когда открывает SQL-коннекшн. Сервис здоров, когда готов выполнять ту работу, для которой задеплоен.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

✏️ Hello World с приколом

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

using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Console.CursorVisible = false;

print('H', ConsoleColor.Red);
print('e', ConsoleColor.Yellow);
print('l', ConsoleColor.Magenta);
print('l', ConsoleColor.Green);
print('o', ConsoleColor.Blue);
print(',', ConsoleColor.Red);
print(' ', ConsoleColor.Red);
print('w', ConsoleColor.Magenta);
print('o', ConsoleColor.Cyan);
print('r', ConsoleColor.Yellow);
print('l', ConsoleColor.Green);
print('d', ConsoleColor.Blue);
print('!', ConsoleColor.Red);
}

static void print(char letter, ConsoleColor color)
{
Console.ForegroundColor = color;
Console.Write(letter);
}
}


Возьмите минутку перерыва и запустите.

💬 А у вас есть любимый бессмысленный кусок кода

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#entry_point

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤨 Вопрос про стриминг на собесе

Эндпоинт возвращает тысячи записей. Что происходит, если просто сделать return Ok(list)?

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

Возникает вопрос:

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


Данные можно отдавать данные по мере готовности, без лишних аллокаций и с контролем над потоком.

➡️ Ответ в библиотеке собеса по C#

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#dotnet_challenge

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Почитали тут свежий отчёт по рынку ИИ-ускорителей в РФ: оказывается, 54% компаний тормозят внедрение ИИ исключительно из-за конских цен на инфраструктуру.

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

По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать time-travel дебаг в LangGraph и уметь роутить запросы на лету. Всё это мы учли в обновлённом курсе по разработке AI-агентов, где акцент сделан именно на AgentOps и жёсткий контроль ресурсов.

Также в программе:

— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу MCP;
— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).

Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.

Прямо сейчас можно урвать курс с увесистой скидкой (49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек), но стоит поторопиться — на потоке осталось всего 5 мест.

👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🛠 Почему C# сравнивает списки по ссылке — и это правильно

Многие удивляются: почему list1.Equals(list2) возвращает false, даже если содержимое одинаковое?

Это не баг и не лень. Это осознанное решение.

Причина 1: равенство коллекций неоднозначно

[1, 2, 3] и [3, 2, 1] — равны? Зависит от задачи:
— порядок важен → нет
— порядок не важен → да
— разные типы (List vs Stack) → может быть

Нет одного правильного ответа, поэтому язык не навязывает ни один.

Причина 2: производительность

Равенство ссылок — O(1).
Сравнение по содержимому — O(n) или O(n log n).
В ранние годы C# строился на скорости.

Причина 3: мутабельность всё ломает

Допустим, вы сравнили два списка, получили true, сохранили флаг. Потом кто-то добавил элемент в один из них. Флаг стал false. равеноство на изменяемых объектах концептуально сломано.

Как правильно

Реализуйте IEqualityComparer<IEnumerable<T>> под свою задачу:

SequenceComparer — порядок важен
ContentComparer — порядок не важен

Вы сами выбираете семантику. Язык не угадывает за вас.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⭐️ Швейцарский нож отказоустойчивости для .NET

Polly — библиотека, которая позволяет описывать стратегии устойчивости: ретрай, circuit breaker, таймаут, rate limiter.

Быстрый старт

dotnet add package Polly.Core


Всё строится через ResiliencePipelineBuilder — стратегии комбинируются цепочкой и применяются в порядке добавления:
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions())
.AddTimeout(TimeSpan.FromSeconds(10))
.Build();

await pipeline.ExecuteAsync(async token => { /* ваша логика */ }, cancellationToken);


Реактивные стратегии

Retry — повторные попытки при сбое:
new RetryStrategyOptions
{
BackoffType = DelayBackoffType.Exponential,
UseJitter = true, // случайный разброс задержки
MaxRetryAttempts = 4,
Delay = TimeSpan.FromSeconds(3),
}


Circuit Breaker — разрывает связь при превышении порога ошибок:
new CircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
// 50% ошибок...
SamplingDuration = TimeSpan.FromSeconds(10),
// ...за 10 секунд
MinimumThroughput = 8,
// при минимум 8 запросах
BreakDuration = TimeSpan.FromSeconds(30),
// разрываем на 30с
}


Fallback — возвращает запасное значение при сбое:
new FallbackStrategyOptions<UserAvatar>
{
FallbackAction = static args => Outcome.FromResultAsValueTask(UserAvatar.Blank)
}


Проактивные стратегии

Timeout — гарантирует, что ожидание не превысит лимит:
new ResiliencePipelineBuilder().AddTimeout(TimeSpan.FromSeconds(3));
// бросает TimeoutRejectedException при превышении


Rate Limiter — ограничивает интенсивность запросов:
// 100 запросов в минуту (скользящее окно)
.AddRateLimiter(new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions
{
PermitLimit = 100,
Window = TimeSpan.FromMinutes(1)
}));


Polly де-факто стандарт во многих командах.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🗺 Подборка вакансий для шарпистов

C#/.NET-разработчик — от 250 000 ₽, удалёнка

Tech Lead (.NET) — от 350 000 ₽, удалёнка

Middle Unity (С#) developer — от 1 500 до 2 700 $, удалёнка

➡️ Еще больше топовых вакансий — в нашем канале C# Jobs

🐸 Библиотека шарписта

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🧑‍💻 F# 11: поддержка #elif в препроцессорных директивах

Раньше при условной компиляции под несколько платформ приходилось вкладывать #if друг в друга. Чем больше веток — тем глубже вложенность и тяжелее читать код.

Теперь F# поддерживает #elif, и цепочки условий пишутся плоско:

#if WIN64
let path = "/library/x64/runtime.dll"
#elif WIN86
let path = "/library/x86/runtime.dll"
#elif MAC
let path = "/library/iOS/runtime-osx.dll"
#else
let path = "/library/unix/runtime.dll"
#endif


В условиях работают &&, || и !, цепочки можно строить произвольной длины, вложенность тоже поддерживается.

Функция входит в F# 11. Чтобы включить, нужно указать --langversion:11.0.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Кажется, мы окончательно перешли от игрушек к суровому AgentOps

Приглашаем на наш обновлённый курс по разработке ИИ-агентов. Никакой воды про «будущее нейросетей», только инженерный подход.

На курсе мы:

— пошагово строим готовые системы на LangGraph, CrewAI и MCP;
— настраиваем кэширование и роутинг, чтобы бот не сожрал токены;
— разбираемся со стейтом, учимся дебажить через time-travel и прикручиваем human-in-the-loop;
— выводим RAG в прод так, чтобы безопасники не завернули архитектуру из-за 152-ФЗ.

В пекло скучные лекции про общую инфраструктуру — сразу фокусируемся на агентных фреймворках и написании кода. Занятия ведут бывалые лиды из Газпромбанка и Альфы, набившие шишки на реальных задачах.

Кстати, на днях мы пилили агента в прямом эфире, если пропустили — есть запись вебинара.


Сегодня последний день, когда можно забрать курс по старым ценам. Базовый тариф сейчас стоит 49 000 ₽ (вместо 62 990 ₽), продвинутый трек — 99 000 ₽ (вместо 124 990 ₽). Если не хочется отдавать всю сумму сразу, есть рассрочка. Торопитесь — на потоке осталось всего 5 мест!

Зафиксировать цену и перейти к сборке своих агентов

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤩 Утилита, которая возвращает правый Ctrl вместо кнопки Copilot

На новых ноутбуках с Copilot+ PC правый Ctrl заменили физической кнопкой Copilot. Microsoft продвигала её как часть сертификации устройств. Те, кто активно использовал правый Ctrl — в VirtualBox, в терминале, при выделении текста — внезапно обнаружили, что кнопки больше нет.

Перепривязать её стандартными средствами Windows нельзя нормально и без костылей.

Разработчик выпустил утилиту NoCopilotKey. Она перехватывает нажатие кнопки Copilot через low-level keyboard hook и подменяет его на Right Ctrl. Никаких настроек, никакого интерфейса.

Скачал, запустил, кнопка работает как Ctrl.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#garbage_collector

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⭐️ F#: упрощённые иерархии интерфейсов с DIM

Раньше при работе с C#-интерфейсами, где базовый слот закрыт через дефолтную реализацию интерфейсов, F# всё равно требовал явно реализовать оба интерфейса.

Теперь достаточно реализовать только производный интерфейс.

Допустим, есть такие C#-интерфейсы:

public interface IA { int M(); }
public interface IB : IA {
new int M();
int IA.M() => this.M() + 100; // DIM покрывает слот IA.M
}


Раньше F# требовал реализовать и IA, и IB. Теперь достаточно IB:
type C() =
interface IB with member _.M() = 42

(C() :> IB).M() // 42
(C() :> IA).M() // 142 — DIM перенаправляет: this.M() + 100


Улучшение работает не только для простых случаев. Поддерживается ромбовидное наследование, дженерик-интерфейсы, свойства, события, структуры и объектные выражения.

Для включения нужен флаг --langversion:preview.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤩 JIT-оптимизации в новом .NET Preview: что улучшилось

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

Устранение проверок границ для паттерна i + cns < len

JIT теперь убирает лишние bounds check в типичном сценарии, когда индекс плюс константа сравниваются с длиной массива. Такой паттерн встречается в парсерах, обработке буферов, посимвольном разборе строк. Раньше каждая такая проверка генерировала лишние инструкции в рантайме.

Удаление избыточных checked-контекстов

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

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

Девиртуализация generic-виртуальных методов в R2R

ReadyToRun-образы теперь умеют девиртуализировать несовместно используемые generic virtual method calls. Это означает, что AOT-скомпилированный код получает те же оптимизации прямых вызовов, которые раньше были доступны только в JIT-режиме.

SVE2-интринсики для ARM

Добавлены новые интринсики ShiftRightLogicalNarrowingSaturate(Even|Odd) для архитектур с поддержкой SVE2. Требуют и поддержки в JIT, и соответствующего API. Полезно для векторных вычислений на серверном ARM-железе вроде Graviton или Neoverse.

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

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻 TarFile.CreateFromDirectory теперь поддерживает выбор формата архива

Продолжаем копаться в превью .NET 11.

До этого TarFile.CreateFromDirectory всегда создавал архивы в формате Pax. Без вариантов. Если нужен был GNU или Ustar — приходилось обходными путями.

Теперь у метода появятся новые перегрузки с параметром TarEntryFormat. Поддерживаются все четыре формата: Pax, Ustar, GNU и V7.

// GNU — для совместимости с Linux-окружениями
TarFile.CreateFromDirectory("/source/dir", "/dest/archive.tar",
includeBaseDirectory: true, TarEntryFormat.Gnu);

// Ustar — широкая совместимость с разными инструментами
TarFile.CreateFromDirectory("/source/dir", outputStream,
includeBaseDirectory: false, TarEntryFormat.Ustar);

// Асинхронный вариант тоже есть
await TarFile.CreateFromDirectoryAsync("/source/dir", "/dest/archive.tar",
includeBaseDirectory: true, TarEntryFormat.Pax, cancellationToken);


Формат имеет значение, когда архив передаётся в конкретный инструмент или среду со своими ожиданиями. GNU лучше воспринимается стандартным tar в Linux.

Ustar даёт максимальную совместимость там, где важна переносимость. V7 нужен в совсем редких легаси-сценариях.

Раньше под такие случаи приходилось либо писать обёртки вручную, либо тянуть сторонние библиотеки. Теперь это часть стандартного API.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Самый востребованный навык в ИТ в 2026-м — навык создания ИИ-агентов

Мы полностью переработали курс «Разработка AI-агентов» под реалии 2026 года. Никакой долгой теории — с самого начала пишем код. Обучать и делиться набитыми шишками будут эксперты-практики из Газпромбанка, Альфа-Банка и других бигтехов.

В программе:

— архитектура автономных систем с тестированием, ReAct-циклами и контролем токенов;
— практическая работа с актуальными фреймворками LangGraph, AutoGen, MCP и CrewAI;
— настройка продвинутого RAG для парсинга документов и точного поиска;
— внедрение решений с учётом действующего законодательства (152-ФЗ);
— дипломная работа, за основу которой можно взять свой рабочий проект или задачу, которую предложим мы.

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

Запись первого открытого вебинара, на котором мы вместе с руководителем AI-направления в Альфа-Банке Полиной Полуниной пилили агента в прямом эфире.


Ах да, чуть не забыли! Дарим промокод AGENTSWEB на скидку 10 000 рублей и два курса сверху при покупке до 15 марта 🎁

Освоить разработку AI-агентов

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚙️ System.Text.Json теперь возвращает типизированные метаданные без приведения типов

Разбираем превью .NET 11.

В .NET появятся два новых метода у JsonSerializerOptionsGetTypeInfo<T>() и TryGetTypeInfo<T>(). Раньше, чтобы получить JsonTypeInfo<T>, приходилось вручную кастовать результат из не-дженерикового GetTypeInfo(Type).

// Раньше
JsonTypeInfo<MyType> info = (JsonTypeInfo<MyType>)options.GetTypeInfo(typeof(MyType));

// Теперь
JsonTypeInfo<MyType> info = options.GetTypeInfo<MyType>();


Если тип может быть не зарегистрирован — есть вариант с TryGetTypeInfo<T>(), который не бросает исключение, а возвращает bool.

if (options.TryGetTypeInfo<MyType>(out JsonTypeInfo<MyType>? typeInfo))
{
// typeInfo готов к работе
}


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

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚡️ Кэширование в .NET 10 с EasyCaching

Если ваш дашборд каждый раз агрегирует данные из нескольких таблиц, а список сотрудников делает новый запрос к БД при каждой загрузке — с десятью пользователями это терпимо. Под реальной нагрузкой всё рассыпается.

EasyCaching решает эту проблему — чистый кэширующий слой, который встраивается в .NET.

Что даёт интеграция:

• Провайдер, TTL и ключи живут в appsettings.json.

Пример:

"PerEndpoint": {
"Dashboard:Metrics": { "AbsoluteTtlSeconds": 300 },
"Employees:GetAll": { "AbsoluteTtlSeconds": 300, "SlidingTtlSeconds": 120 }
}


• MediatR Pipeline: кэш оборачивает query-хендлер прозрачно. Хэндлер вообще не знает, что его результаты кэшируются.

var cached = await _cache.GetAsync<TResponse>(cacheKey);
if (cached != null) return cached;

var result = await next(); // реальный запрос к БД
await _cache.SetAsync(cacheKey, result, CacheKeyPrefixes.EmployeesAll);
return result;


• Domain Events инвалидация: CacheInvalidationEventHandler автоматически сбрасывает кэш при любой записи. RemoveByPrefixAsync чистит все Employees:GetAll:* за раз, без перебора ключей.

• Диагностические заголовки X-Cache-Status: HIT/MISS в каждом ответе. Видно прямо в DevTools — кэш работает или нет.

• Админские эндпоинты: POST /cache/invalidate и GET /cache/stats для ручного управления

Кэширование — это инфраструктура, не бизнес-логика. Хендлеры не знают о кэше, команды не знают об инвалидации.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…
Subscribe to a channel