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

Архитектура ИИ-агентов: учим матчасть

Пока Microsoft развивает Semantic Kernel, индустрия стандартизирует паттерны на Python. Курс «Разработка ИИ-агентов» поможет понять принципы построения таких систем, независимо от вашего основного языка.

Что в программе:

— графовая оркестрация (LangGraph);
— работа с памятью и контекстом (RAG);
— мультиагентные протоколы.

Кодим на Python (нужны базовые знания), но полученные архитектурные скиллы универсальны. Первая лекция уже доступна.

Смотреть лекцию

Записаться на курс

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

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

📎 Делимся заметками красиво

Вы написали отличную заметку в Markdown в Obsidian, Notion или обычном редакторе, а теперь нужно отправить её коллеге или начальнику в Google Docs.

Копируете текст и... все форматирование слетает. Заголовки превращаются в решётки ###, списки ломаются, код выглядит убого.

Решение: md2cb

Простая утилита, которая конвертирует ваш Markdown в богатый HTML и кладёт в буфер обмена. Просто:

cat заметка.md | md2cb
# Ctrl+V в любое приложение


Есть флаг -e для быстрого редактирования:
md2cb -e  # открывает $EDITOR, конвертирует после сохранения


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

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

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

#sharp_view

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

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

☝️ Не повторяйтесь

Принцип DRY (Don't Repeat Yourself) — один из самых известных в программировании. Но, как и любой принцип, его можно применять неправильно. Давайте разберёмся, когда следовать DRY, а когда от него отступить.

Признаки over-DRYing

• Функция с 5+ параметрами:

// Универсальная функция-монстр
public async Task<object> FetchDataAsync(
string entityType, int? id, string filter,
int pageSize, bool includeDeleted, params string[] includes) { }

// Специализированные методы
public async Task<List<User>> GetActiveUsersAsync(int page, int pageSize)
=> await _context.Users.Where(u => u.IsActive)
.Skip(page * pageSize).Take(pageSize).ToListAsync();


• Generic Repository:
// Кажется умным, но бесполезен
public interface IRepository<T> where T : class
{
Task<T> GetByIdAsync(int id);
Task<IEnumerable<T>> GetAllAsync();
}

// Специфичный и полезный
public interface IUserRepository
{
Task<User> GetByEmailAsync(string email);
Task<User> GetWithOrdersAsync(int id);
}


Когда дублирование правильно

• Случайное совпадение:
// НЕ объединяйте! Разные бизнес-концепции
public string FormatUserName(User u) => $"{u.FirstName} {u.LastName}";
public string FormatProductName(Product p) => $"{p.Brand} {p.Model}";


• Разные контексты:
// UI: простая проверка
public bool ValidateEmail(string email) => email.Contains("@");

// API: строгая проверка
public bool ValidateEmail(string email) =>
Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");


Повторите код три раза, прежде чем рефакторить:

Первый раз — пишите
Второй раз — терпите
Третий раз — рефакторьте

Дублирование в тестах — нормально:
[Fact]
public void CreateUser_ShouldSucceed()
{
var user = new User { Name = "Alice", Age = 25 };
Assert.Equal("Alice", _service.CreateUser(user).Name);
}

[Fact]
public void UpdateUser_ShouldSucceed()
{
var user = new User { Name = "Alice", Age = 25 }; // OK
// Читаемость важнее DRY
}


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

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

#sharp_view

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

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

🕶 Работа сама себя не найдёт

Senior .NET Engineer — до 450 000₽ с удалёнкой.

C# разработчик
на удалёнку с ЗП до 250 000 ₽

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

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

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

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

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

👨‍💻 Оптимизации с константами

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

Самая простая оптимизация называется constant folding. Суть в том, что компилятор не будет заставлять процессор каждый раз высчитывать одно и то же. Если вы пишете int result = 10 * 5 + 3 * 2, компилятор прекрасно понимает, что результат всегда будет 56, и именно это число окажется в скомпилированном коде.


public void Example()
{
int result = 10 * 5 + 3 * 2; // Вы пишете это
// Компилятор превращает в:
int result = 56; // Уже посчитано
}


Более интересная оптимизация – constant propagation. Когда вы объявляете константу через const, компилятор запоминает её значение и подставляет его везде, где она используется.

public void ConstantPropagation()
{
const int multiplier = 100;
int value = 42;
int calculated = value * multiplier;

// Компилятор оптимизирует до:
int calculated = value * 100; // multiplier заменен значением
}


Оптимизация строк

С строками всё еще интереснее. Когда вы конкатенируете несколько строковых литералов, компилятор склеивает их в один. Код string message = "Hello" + " " + "World"; превращается в string message = "Hello World";

public void StringOptimization()
{
// Все литералы склеиваются в один
string message = "Hello" + " " + "World";
// Результат: string message = "Hello World";

// С константами тоже работает частично
const string greeting = "Hello";
string name = "Alice";
string message = greeting + " " + name;
// Результат: string message = "Hello " + name;
}


Используйте const там, где это уместно, не бойтесь записывать формулы явно вместо магических чисел – компилятор сам посчитает результат.

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

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

#il_люминатор

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

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

🚀 Git v2.53

Вышла новая версия системы контроля версий Git v2.53. Разбираем ключевые изменения.

Новые команды

git maintenance is-needed — проверка, нужно ли выполнять задачи обслуживания репозитория.

git repo info --all — показывает расширенную информацию о структуре репозитория.

git blame --diff-algorithm=<algo> — теперь можно выбрать алгоритм сравнения при отслеживании изменений.

Улучшения существующих команд

git replay — теперь выполняет обновление ссылок самостоятельно, не требуя дополнительных команд.

git fast-import — новая опция --signed-commits=strip-if-invalid для удаления невалидных подписей.

git apply и git diff — новый класс ошибок пробелов incomplete-line.

И многие другие мелкие доработки.

➡️ Анонс

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

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

#async_news

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

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

⚙️ Оптимизация C#: Inlining методов

Инлайнинг (Inlining) — замена вызова метода его телом напрямую в месте вызова. JIT-компилятор делает это автоматически для маленьких методов, которые весят меньше 32 байт.

Зачем это делается

• Убирает overhead вызова метода

• Улучшает локальность кода

• Даёт прирост в 5-7 раз для горячих путей

Пример

Без инлайнинга:

public int Calculate(int a, int b)
{
return Add(a, b) * 2;
}

private int Add(int a, int b) // JIT заинлайнит автоматически
{
return a + b;
}


Что делает JIT:
public int Calculate(int a, int b)
{
return (a + b) * 2; // тело Add() вставлено напрямую
}


Принудительный инлайнинг:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int Multiply(int a, int b)
{
return a * b;
}


Не гадайте — профилируйте. Иногда JIT делает лучше без вашей помощи.

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

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

#sharp_view

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

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

Semantic Kernel или LangGraph?

В мире .NET популярен Semantic Kernel, но глобальный стандарт задаёт LangGraph. Его киллер-фича — явное управление графом выполнения и состоянием (Stateful Graph).

Это позволяет реализовывать сложные паттерны: Human-in-the-loop (человек подтверждает действие), Time Travel (откат состояния назад) и цикличное планирование. Понимание этих принципов пригодится любому разработчику, внедряющему AI.

Записаться на курс

Погружение в архитектуру агентов: Смотрите вводный урок бесплатно.

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

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

7️⃣ Генерация случайных чисел в C#

Класс Random в .NET генерирует псевдослучайные числа для игр, тестов или симуляций. Он работает на основе сида, обычно времени, и дает целые, дробные значения или байты.

Основы класса Random

System.Random создает последовательности чисел через алгоритм. Для простого инта берут Next(min, max), где верхняя граница не включается.

Переиспользуйте один экземпляр, иначе в цикле из-за одинаковых сидов выйдут повторения. Статический или инжектированный через DI вариант подходит для прода:

var rng = new Random();
int число = rng.Next(1, 101); // от 1 до 100


NextDouble возвращает от 0.0 до 1.0, умножьте и сдвиньте для нужного интервала. Байты через NextBytes заполняют массив. Это для тестовых файлов или симуляций.
double температура = rng.NextDouble() * 50 - 10; // от -10 до 40
byte[] буфер = new byte[16];
rng.NextBytes(буфер);


Обычный Random не годится для токенов или паролей, предсказуем при известном сиде. Берите RandomNumberGenerator из System.Security.Cryptography для криптографии.

GetInt32(1, 101) или Fill для байт. В API для ключей всегда крипто-вариант.

Random не потокобезопасен, общий экземпляр сломается. ThreadLocal<Random> создаст по инстансу на поток. Parallel.For с ним работает корректно, без гонок:
var локальныйRng = new ThreadLocal<Random>(() => new Random());
Parallel.For(0, 100, i => {
int значение = локальныйRng.Value!.Next(100);
});


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

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

#il_люминатор

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

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

📎 Фабрика HttpClient в .NET

В .NET для HTTP-запросов фабрика IHttpClientFactory упрощает создание клиентов, интегрируется с DI и решает проблемы вроде утечек сокетов.

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

Зачем нужна фабрика

HttpClient из Framework 4.5 часто создают вручную, но это приводит к проблемам: сокеты не освобождаются, DNS не обновляется. Фабрика решает это через пул обработчиков с лайфтаймом в 2 минуты по умолчанию.

Она регистрируется через AddHttpClient в IServiceCollection и дает доступ к CreateClient. Короткоживущие клиенты подходят для большинства случаев, в отличие от долгоживущих с PooledConnectionLifetime.

Предупреждение: если нужны куки, лучше обойтись без фабрики из-за шаринга CookieContainer.

Способы использования

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

В базовом варианте инжектят IHttpClientFactory и вызывают CreateClient для каждого запроса. Это просто для рефакторинга старого кода.

Именованные клиенты настраивают по имени из конфига, с базовым URI и заголовками вроде User-Agent:

builder.Services.AddHttpClient("MyClient", client =>
{
client.BaseAddress = new Uri("https://api.example.com/");
client.DefaultRequestHeaders.UserAgent.ParseAdd("MyApp");
});


Затем CreateClient("MyClient").

Типизированные удобны для конкретного API: класс принимает HttpClient в конструкторе, фабрика регистрирует его через AddHttpClient<T>.

Логика запросов инкапсулируется в методах класса, DI все подхватывает. IntelliSense работает, нет строковых ключей.

Не используйте в синглтонах: клиент должен быть короткоживущим, иначе DNS не обновится. Лучше именованные или SocketsHttpHandler:
public class ApiService(HttpClient client)
{
public async Task<Todo[]> GetTodos(int id) =>
await client.GetFromJsonAsync<Todo[]>($"todos/{id}");
}


В итоге фабрика делает HTTP-клиенты в .NET предсказуемыми и масштабируемыми. Для прода это как стандарт: меньше багов с соединениями, проще DI.

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

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

#il_люминатор

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

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

🎯 Нестандартные форматы резюме

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

➡️ В статье ещё два формата

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

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

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

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

🔛📈 Включаем фичи без редеплоя

Feature Flags — это условные переключатели, которые позволяют включать/выключать фичи на лету, без передеплоя приложения.

Зачем они нужны

• Безопасный rollout — можно включить фичу для 10% пользователей, проверить метрики, затем раскатывать дальше.

• A/B тестирование — запуск двух версий фичи и выбор лучшей на основе данных.

• Eсли что-то пошло не так, флаг выключается за секунду вместо отката всего деплоя.

• Возможность коммитить незавершённый код без риска для продакшна

Подготовка:

// Добавим NuGet пакет
dotnet add package Microsoft.FeatureManagement

// В appsettings.json
"FeatureManagement": {
"NewDashboard": false
}


В коде:

if (await featureManager.IsEnabledAsync("NewDashboard"))
{
RenderNewDashboard();
}
else
{
RenderOldDashboard();
}


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

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

#sharp_view

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

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

AI-агенты в экосистеме .NET: расширяем границы возможного

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

Курс «Углубленные AI-агенты» даст вам глубокую экспертизу в актуальном стеке.

На обучении вас ждёт:

— проектирование автономных агентских систем;
— освоение LangGraph, CrewAI и AutoGen;
— интеграция RAG и инструментов планирования;
— 13 живых вебинаров и поддержка менторов.

Поток уже стартовал, присоединяйтесь сейчас.

🚀 Записаться на основной курс

Если сомневаетесь — просто посмотрите вводное занятие.

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

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

⚙️ Вы настраиваете ASP.NET Core «по наитию» и тратите время на поиск, почему приложение ведет себя по-разному в продакшене и локально?

🗓 29 января в 20:00 OTUS проводит открытый урок «Конфигурирование приложения ASP.NET Core» в преддверии старта курса «C# ASP.NET Core разработчик».

На занятии разберем, как выстроить прозрачную и управляемую систему настроек: appsettings.json, провайдеры конфигурации, приоритет применения конфигураций, настройки специфичные для среды и шаблон Options для работы с настройками. Вы поймете, как проектировать конфигурации так, чтобы приложения были стабильными и предсказуемыми.

❗️Урок будет полезен разработчикам ASP.NET Core начального и среднего уровня, которые хотят систематизировать знания и работать по индустриальным стандартам.

➡️ Регистрируйтесь на бесплатный урок: https://clc.to/JVrtgw

🎁 Все участники открытого урока получат скидку на обучение.

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

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

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

🛋 Работа в кайф

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

➡️ В статье 10 базовых советов по обустройству вашего рабочего места

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

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

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

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

Вопрос с собеса

Что такое абстракция в ООП?


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

Ключевое слово здесь — упрощение. Абстракция — ответ в канале с вопросами с собесов

Всё остальное — несущественные детали.

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

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

#dotnet_challenge

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

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

🤩 Работа с LLM в .NET

Microsoft выпустили разбор про то, как работать с AI в .NET. Если вы думали, что интеграция LLM — это боль и каша из разных SDK, вот хорошие новости.

Microsoft.Extensions.AI — один API для всех

Работаете с OpenAI — один SDK. Решили попробовать Ollama — другой API. Захотели Azure OpenAI — третий подход. Microsoft решили эту проблему радикально: один интерфейс для всех провайдеров.

IChatClient client = ...; // любой провайдер
await foreach (var update in client.GetStreamingResponseAsync("How are you?"))
{
Console.Write(update);
}


Раньше, чтобы получить структурированный JSON, нужно было плясать с бубном и JSON Schema. Теперь:
record Family(List<Person> Parents, List<Person>? Children);
record Person(string Name, int Age);

var family = await client.GetResponseAsync<Family>(
[
new ChatMessage(ChatRole.System, "You are an AI assistant..."),
new ChatMessage(ChatRole.User, "Create a family with 2 parents...")
]);


Схему сгенерируют за вас, JSON распарсят, десериализуют.

Хотите отправить фото для анализа? Обойдёмся без сотни строк:
var image = new DataContent(File.ReadAllBytes(@"photo.jpg"), "image/jpeg");
var messages = new List<ChatMessage>
{
new(ChatRole.System, "You are a photo analyst..."),
new(ChatRole.User, [prompt, image])
};

record ImageAnalysis(string Description, string[] Tags);
var analysis = await client.GetResponseAsync<ImageAnalysis>(messages);


Работает с изображениями, аудио и видео.

Один API, middleware, типизация, телеметрия. Можно не изобретать велосипед при каждой смене провайдера.

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

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

#sharp_view

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

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

🤖 Миграция с GitHub

Если следите за IT-комьюнити, то наверняка замечали: всё больше программистов переезжают с GitHub. Недавно оттуда мигрировали язык программирования Zig и инструмент Leiningen, а за ними — сотни индивидуальных разработчиков.

В чём проблема

• GitHub стал хуже технически

После покупки Microsoft в 2018 платформа деградирует: интерфейс грузится дольше, GitHub Actions запускает джобы случайно и сам интерфейс раздут до безобразия.

• Copilot — это плагиат

GitHub Copilot буквально выдаёт куски кода дословно. Это нарушение лицензий и воровство чужого кода. Software Freedom Conservancy (те, кто поддерживают Wine, Git, QEMU) организовали кампанию «Give Up GitHub» именно из-за этого.

• Закрытая платформа для открытого кода

Парадокс: серверная часть GitHub — проприетарный софт. Вы размещаете open-source проекты на закрытой платформе, которую контролирует Microsoft.

В отличие от Instagram или Twitter, GitHub не контролирует дистрибуцию контента. Уход с GitHub — это небольшая неудобство для контрибьюторов, но не исчезновение из поля зрения.

Куда переезжать

Бесплатно и с хостингом:

• Codeberg (Forgejo) — некоммерческий проект, для FOSS
• SourceHut — платно $4-12/мес, но есть финпомощь
• GitLab — бесплатный тариф с ограничениями

Самохостинг:

• Gitea — простой и лёгкий
• Gogs — ещё проще
• Gerrit — если нужен продвинутый code review

Децентрализация:

• Radicle — p2p git
• Или просто свой скрипт, заливающий в S3

💬 Где вы держите свои проекты?

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

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

#entry_point

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

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

💡 Фриланс для разработчиков

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

➡️ В статье 9 способов найти первые проекты без бирж

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

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

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

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

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

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

#garbage_collector

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

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

🆚 Namespace vs Assembly

Давайте разберёмся, чем отличается namespace от assembly.

Namespace — это логическая организация кода.
Assembly — это физический файл на диске.

Они существуют в разных измерениях и решают разные задачи.

Namespace (пространство имён) — это способ логической группировки классов, интерфейсов и других типов, чтобы избежать конфликтов имён:

namespace MyCompany.PaymentSystem
{
public class PaymentProcessor
{
// ...
}
}

namespace MyCompany.Logging
{
public class Logger
{
// ...
}
}


Зачем нужны namespace

• Без namespace два класса с именем Logger конфликтуют. С namespace можно иметь MyApp.Logger и ThirdPartyLib.Logger одновременно.

• Организация кода по доменам: MyCompany.Ecommerce.Orders, MyCompany.Ecommerce.Products, MyCompany.Ecommerce.Payments.

• Упрощённое использование кода с using

using MyCompany.Ecommerce.Orders;

var order = new Order(); // Вместо: new MyCompany.Ecommerce.Orders.Order()


Можно объявить namespace один раз для всего проекта:
// GlobalUsings.cs
global using System;
global using MyCompany.Core;


Что такое Assembly

Assembly (сборка) — это скомпилированный физический файл на диске .dll или .exe, который содержит IL-код и метаданные.

.exe — приложение, которое можно запустить.
.dll — библиотека для подключения.

Как они связаны

Подключение сборки:
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />

Это добавляет assembly в проект.

Использование namespace:
using Newtonsoft.Json;  // Импортируем namespace

var json = JsonConvert.SerializeObject(obj);

//или без using

var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);


Один работает на уровне файлов, другой — на уровне кода.

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

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

#il_люминатор

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

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

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

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

#garbage_collector

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

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

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

В .NET-среде штиль, новостей не так много, поэтому вспоминаем лучшее за неделю.

IoT на .NET

ExecuteUpdate и ExecuteDelete

Коты вместо HTTP статусов

10 советов по обустройству вашего рабочего места

Нестандартные форматы резюме

Делитесь в комментах своими инфоповодами недели 👇

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

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

#async_news

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

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

🧑‍💻 Неявная проверка на null

В C# можно заставить любой класс вести себя в if как в JavaScript: просто if (myObject) и внутри проверка на null. Это работает благодаря перегрузке операторов.

Создайте класс с двумя статическими методами:

public class User
{
public string Name { get; set; }

public static bool operator true(User? user) => user?.Name != null;
public static bool operator false(User? user) => user?.Name == null;
}


Теперь if (user) сработает если имя задано, иначе попадет в else. Компилятор автоматически вызывает нужный оператор при булевом контексте.

Единственный минус: никто не ожидает такого, код становится загадкой для команды. Лучше стандартные is not null или !ReferenceEquals(null, obj).

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

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

#sharp_view

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

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

LangGraph vs Semantic Kernel: архитектура агентов

В .NET мире популярен Semantic Kernel, но индустрия движется к графовым подходам. LangGraph реализует паттерн, где агент — это не просто цепочка плагинов, а граф с состоянием.

Архитектурные преимущества:

— цикличность: нативная поддержка циклов (ReAct pattern);
— state management: управление контекстом похоже на работу с сессиями;
— human-in-the-loop: возможность поставить граф на паузу, получить апрув человека и продолжить.

Курс по архитектуре уже стартовал.

Записаться на курс

Смотреть первую лекцию бесплатно

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

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

📎 ValueTask в публичном API

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

Вопрос: чем так плох ValueTask в публичном API? Он же снизит аллокации

Ответ: у нас в канале с вопросами с собесов

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

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

#dotnet_challenge

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

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

⚡️ ExecuteUpdate и ExecuteDelete в EF Core

ExecuteUpdate и ExecuteDelete появились для случаев, когда вам не нужны сущности и сложные хуки.

Это способ выполнять быстрые массовые операции, говоря с базой на языке SQL через LINQ.

Простой пример с заказами, которые нужно отметить как просроченные:

public async Task<IActionResult> ExpireOldOrders()
{
var cutoff = DateTime.UtcNow.AddDays(-30);

var affectedRows = await _db.Orders
.Where(o => o.Status == OrderStatus.Pending
&& o.CreatedAt < cutoff)
.ExecuteUpdateAsync(setters =>
setters.SetProperty(
o => o.Status,
OrderStatus.Expired));

return Ok(new { affectedRows });
}


EF Core сгенерирует один SQL примерно такого вида:
UPDATE Orders
SET Status = 2
WHERE Status = 0
AND CreatedAt < @cutoff


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

ExecuteDelete решает такую же задачу для удаления:
public async Task<int> CleanOldLogsAsync(DateTime cutoff)
{
var affected = await _db.Logs
.Where(l => l.CreatedAt < cutoff)
.ExecuteDeleteAsync();

return affected;
}


EF Core не загружает логи в память — удаление происходит одним SQL-запросом.

Важно: эти методы обходят change tracking и не вызывают события SaveChanges.
Используйте их, когда производительность важнее бизнес-логики в коде.

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

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

#il_люминатор

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

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

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

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

#garbage_collector

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

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

📞 Как доска объявлений, но отборная

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

С# разработчик от 200 000 ₽ и снова удалёнка.

.NET Developer внезапный офис в Новосибирске.

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

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

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

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

🐳 Docker для быстрого запуска сервисов локально

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

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

Достаточно выполнить:

docker run -p 27017:27017 mongo


Эта команда скачает официальный образ mongo с Docker Hub и запустит контейнер. Флаг -p 27017:27017 пробрасывает порт на хост, то есть вы обращаетесь к базе на localhost:27017.

Так вы получаете рабочую MongoDB без отдельной установки сервера, настройки сервисов и борьбы с конфликтами версий.

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

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

#sharp_view

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