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

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

Открыть в Telegram

Все самое полезное для C#-разработчика в одном канале. Наши курсы: https://clc.to/y3LDtw По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Больше

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

Канал Библиотека шарписта | C#, F#, .NET, ASP.NET (@csharpproglib) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 21 708 подписчиков, занимая 5 953 место в категории Технологии и приложения и 30 278 место в регионе Россия.

📊 Показатели аудитории и динамика

С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 21 708 подписчиков.

Согласно последним данным от 28 августа, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -37, а за последние 24 часа — 5, при этом общий охват остаётся высоким.

  • Статус верификации: Не верифицирован
  • Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 16.02%. В первые 24 часа после публикации контент обычно набирает 7.85% реакций от общего числа подписчиков.
  • Охват публикаций: В среднем каждый пост получает 3 478 просмотров. В течение первых суток публикация набирает 1 705 просмотров.
  • Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 26.
  • Тематические интересы: Контент сосредоточен на ключевых темах, таких как .net, шарписта, навигация, await, string.

📝 Описание и контентная политика

Автор описывает ресурс как площадку для выражения субъективного мнения:
Все самое полезное для C#-разработчика в одном канале. Наши курсы: https://clc.to/y3LDtw По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Благодаря высокой частоте обновлений (последние данные получены 29 августа, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.

21 708
Подписчики
+524 часа
-57 дней
-3730 день
Архив постов
🔄 Дайджест недели Коротко про события недели. — Microsoft разрабатывает функцию перемещения панели задач в Windows 11 Функци
🔄 Дайджест недели Коротко про события недели. — Microsoft разрабатывает функцию перемещения панели задач в Windows 11 Функция ожидается летом 2026 года как часть усилий по улучшению репутации ОС. — Linux 6.19Превью .NET 11Бустим рабочее место за 10 шагов 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #async_news

📎 Пропущенный аудит Метод ExecuteUpdate в EF Core ускоряет массовые обновления, но пропускает перехватчики и события SaveChanges. Это может сломать аудит изменений. Перехватчик SaveChanges ловит изменения из трекера. Но ExecuteUpdate работает напрямую с БД и игнорирует его:
public override async Task<int> SaveChangesAsync(CancellationToken ct = default)
{
    // Захватывает изменения от SaveChanges
    var entries = ChangeTracker.Entries()
        .Where(e => e.State == EntityState.Modified);
    
    // Но не от ExecuteUpdate!
}
Решение через ручной аудит Добавляйте аудит вручную перед или после ExecuteUpdate:
await context.Products
    .Where(p => p.CategoryId == categoryId)
    .ExecuteUpdateAsync(s => s
        .SetProperty(p => p.Price, newPrice)
        .SetProperty(p => p.ModifiedAt, DateTime.UtcNow)
        .SetProperty(p => p.ModifiedBy, currentUser));

// Отдельная запись аудита
context.AuditLogs.Add(new AuditLog
{
    Action = "BulkPriceUpdate",
    EntityType = "Product",
    Details = $"Обновил CategoryId={categoryId}, цена={newPrice}"
});
await context.SaveChangesAsync();
Альтернативы для полного аудита • Триггеры на уровне БД ловят все изменения, включая ExecuteUpdate. Минус — сложнее тестировать и отлаживать. • Библиотеки расширения EF предлагают BulkUpdate с встроенным аудитом через опции UseAudit. 📍 Навигация: ВакансииЗадачиСобесы 🐸Библиотека шарписта #sharp_view

📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека шарписта #garbage_collector
📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #garbage_collector

⚡️ C# убил Builder для простых случаев Target-typed new убирает дублирование типов при инициализации, а with-выражения делают иммутабельные обновления одной строкой кода. Раньше при создании объекта приходилось дважды писать тип: var user = new UserDto { ... }. Теперь достаточно User user = new() { ... }. Компилятор выводит тип из контекста — при возврате из методов, в параметрах, элементах коллекций Работа с иммутабельными объектами традиционно требовала copy-конструкторов, Builder'а или AutoMapper. with-выражение создаёт поверхностную копию с изменением указанных свойств: var updated = user with { Age = 31 }. Компилятор генерирует код копирования автоматически. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

Собираем фулл-хаус: 3 курса по цене 1 Хватит выбирать между «полезно», «модно» и «для души». Мы запустили механику, которая п
Собираем фулл-хаус: 3 курса по цене 1 Хватит выбирать между «полезно», «модно» и «для души». Мы запустили механику, которая позволяет собрать кастомный стек навыков без удара по бюджету: покупаете один курс — два других забираете бесплатно. В Enterprise ценится фундаментальность. Углубитесь в архитектуру и шаблоны проектирования для построения сложных систем или подтяните алгоритмы и структуры данных для технических интервью. Для тех, кто хочет понимать математику ML-моделей (вне зависимости от языка) — полный набор по AI: от линала и ML-старта до разработки автономных агентов. Ну и классика: обновлённый Python как второй язык для скриптов. Собрать свой пак

👨‍💻 Span<T> как ref struct Разбираем вопрос с собеса, в этот раз про Span. Span<T> даёт доступ к памяти без копий и аллокаций. Но почему его сделали ref struct с кучей запретов, и когда лучше взять Memory<T>? Ответ лежит в нашем канале с вопросами с собесов 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #dotnet_challenge

🧑‍💻 Когда чистый код всё равно требует комментариев Чистый код делает программу понятной без лишних объяснений. Но иногда к
🧑‍💻 Когда чистый код всё равно требует комментариев Чистый код делает программу понятной без лишних объяснений. Но иногда комментарии необходимы, чтобы передать суть решений, которые не уместить в самих строках. Роберт Мартин в книге «Чистый код» не запрещает комментарии полностью. Он против тех, что дублируют очевидное или устаревают со временем. Когда комментарии спасают ситуацию • Сложная логика или хак:
// Обход бага в IE11 с обработкой форм
if (isIE11()) {
    polyfillFormSubmit();
}
• Предупреждения о рисках:
// Не трогать: изменение сломает кэш в проде до деплоя новой версии
cache.invalidateOnlyOnRestart();
• Указание на патенты, стандарты или тикеты в баг-трекере. 💬 Когда, по вашему мнению, ещё могут пригодиться комментарии в коде 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #il_люминатор

📂 File-Scoped Namespaces Cинтаксис file-scoped namespaces заменяет привычное объявление пространства имён со скобками на одн
📂 File-Scoped Namespaces Cинтаксис file-scoped namespaces заменяет привычное объявление пространства имён со скобками на однострочное с точкой с запятой. Раньше каждый файл в C# проекте начинался с namespace MyApp.Services { ... }, что добавляло один уровень отступа ко всему коду внутри. Теперь достаточно написать namespace MyApp.Services; в начале файла, и всё содержимое автоматически находится в этом пространстве имён без дополнительной вложенности. Код становится более плоским. Вместо того чтобы начинать каждый класс с двух уровней отступа: namespace + class, вы сразу работаете с одним. При рефакторинге, когда нужно переместить класс в другой namespace, старый подход требовал изменения строки с объявлением. В git diff это выглядело как замена всего файла, даже если логика класса не менялась. C новым подходом меняется только одна строка вверху. Компилятор не видит разницы — это чисто синтаксический сахар. IL-код идентичен, производительность не меняется. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

🧑‍💻 Композиция функций в C# Функциональное программирование — не просто академическая теория. Это парадигма, превращающая императивный спагетти-код в декларативные, тестируемые и поддерживаемые решения. Проблема императивного кода:
// Традиционный подход - может быть трудно читать и сложно тестировать
public OrderDto ProcessOrder(int orderId)
{
    var order = _dbContext.Orders.Find(orderId);
    if (order == null) throw new NotFoundException();
    
    if (order.Status != "Pending") 
        throw new InvalidOperationException();
    
    var customer = _dbContext.Customers.Find(order.CustomerId);
    if (!customer.IsActive) 
        throw new InvalidOperationException();
    
    var discount = customer.IsVip ? 0.1m : 
                   order.Total > 1000 ? 0.05m : 0m;
    
    order.FinalTotal = order.Total * (1 - discount);
    _dbContext.SaveChanges();
    
    return new OrderDto { ... };
}
Проблемы: смешанные обязанности, жёсткая связанность с БД, невозможность переиспользования, хрупкость при изменениях. Композиционное решение:
public class OrderProcessingPipeline
{
    private readonly Func<int, Task<Order?>> _loadOrder;
    private readonly Func<Order, Task<Customer?>> _loadCustomer;
    
    public async Task<Result<OrderDto, Error>> ProcessAsync(int orderId)
    {
        return await Result<Order, Error>
            .FromNullable(await _loadOrder(orderId), Error.OrderNotFound)
            .BindAsync(_loadCustomer)
            .BindAsync(_validateStatus)
            .BindAsync(_calculateDiscount)
            .BindAsync(_persistOrder)
            .MapAsync(_mapToDto);
    }
}
Преимущества: единственная ответственность каждой функции, простота тестирования, композируемость, декларативный флоу. Основа композиции — чистые функции без побочных эффектов:
public static class PricingFunctions
{
    public static decimal CalculateDiscount(CustomerType type, decimal total) => 
        type switch
        {
            CustomerType.Vip => total * 0.15m,
            CustomerType.Premium => total * 0.10m,
            _ => 0m
        };
    
    public static decimal ApplyTax(decimal amount, decimal rate) => 
        amount * (1 + rate);
    
    // Композиция
    public static Func<CustomerType, decimal, decimal> CalculateFinalPrice => 
        (type, total) => ApplyTax(total - CalculateDiscount(type, total), 0.08m);
}
Тест такой функции:
[Theory]
[InlineData(CustomerType.Vip, 1000, 918.00)]
public void CalculateFinalPrice_ReturnsExpected(CustomerType type, decimal total, decimal expected)
{
    Assert.Equal(expected, PricingFunctions.CalculateFinalPrice(type, total));
}
Начните с малого: замените один цикл на Map, один if/throw на Result. Паттерны быстро станут естественными, и ваша кодовая база скажет спасибо. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #il_люминатор

🌼 Бустим рабочее место за 10 шагов Удаленка — это не только про свободу выбора места работы, но и про умение создать условия
+5
🌼 Бустим рабочее место за 10 шагов Удаленка — это не только про свободу выбора места работы, но и про умение создать условия для продуктивности. ➡️ В карточках 5 советов по обустройству рабочего места, а остальные в статье. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта

📂 File-Scoped Namespaces Cинтаксис file-scoped namespaces заменяет привычное объявление пространства имён со скобками на одн
📂 File-Scoped Namespaces Cинтаксис file-scoped namespaces заменяет привычное объявление пространства имён со скобками на однострочное с точкой с запятой. Раньше каждый файл в C# проекте начинался с namespace MyApp.Services { ... }, что добавляло один уровень отступа ко всему коду внутри. Теперь достаточно написать namespace MyApp.Services; в начале файла, и всё содержимое автоматически находится в этом пространстве имён без дополнительной вложенности. Код становится более плоским. Вместо того чтобы начинать каждый класс с двух уровней отступа: namespace + class, вы сразу работаете с одним. При рефакторинге, когда нужно переместить класс в другой namespace, старый подход требовал изменения строки с объявлением. В git diff это выглядело как замена всего файла, даже если логика класса не менялась. C новым подходом меняется только одна строка вверху. Компилятор не видит разницы — это чисто синтаксический сахар. IL-код идентичен, производительность не меняется. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

📷 Подборка вакансий для шарпистов C#/.NET разработчик — 265 000 ₽. Удалёнка Middle/Senior .NET Developer — от 3 000 до 3 500 $. Удалёнка C#/.NET-разработчик — Удалёнка ➡️ Еще больше топовых вакансий — в нашем канале C# Jobs 🐸 Библиотека шарписта

⚡️ Почему IQueryable не должен покидать слой данных Разработчики используют EF Core и передают IQueryable по всему приложению, считая это эффективным подходом. Но такая практика создаёт серьёзные проблемы с архитектурой и сопровождением кода. IQueryable позволяет строить динамические SQL-запросы, выполняя фильтрацию на стороне БД, а не в памяти приложения:
var startDate = new DateTime(2023, 1, 1);

// Плохо: загружаем всё в память, затем фильтруем
var allRecords = context.Purchases.ToList();
var filtered = allRecords.Where(p => p.Date > startDate).ToList();

// Хорошо: фильтрация выполняется базой данных
var filtered = context.Purchases
    .Where(p => p.Date > startDate)
    .ToList();
Второй подход быстрее и эффективнее. Но когда IQueryable начинает путешествовать через слои приложения, возникают проблемы. Антипаттерн: распространение IQueryable. Типичный сценарий — IQueryable передаётся через слои:
// Репозиторий
public class PurchaseRepository
{
    public IQueryable<Purchase> GetAll() => 
        _context.Purchases.AsQueryable();
}

// Сервис бизнес-логики
public class PurchaseService
{
    public IQueryable<Purchase> GetActive() => 
        _repository.GetAll().Where(p => p.Status == "Active");
}

// Контроллер
var userPurchases = _service.GetActive()
    .Where(p => p.UserId == currentUserId);

// Представление
@foreach(var item in Model.Where(p => p.IsCompleted)) 
{
    <!-- рендеринг -->
}
Проблемы: • Логика доступа к данным размазана по всему приложению • Нарушен принцип единственной ответственности • IQueryable наследует IEnumerable — код может не знать, что работает с запросом к БД • Исключения в runtime, если EF не может преобразовать код в SQL • Сложное тестирование и отладка Решить эти проблемы можно, к примеру, паттерном спецификация, или, если спецификации избыточны, передавайте выражения:
public interface IPurchaseRepository
{
    Task<List<Purchase>> FindAsync(Expression<Func<Purchase, bool>> predicate);
}

// Использование
var purchases = await _repository.FindAsync(
    p => p.IsCompleted && p.UserId == currentUserId);
Запрос по-прежнему выполняется в БД, но логика доступа к данным инкапсулирована. 💬 Как бы вы решили эту проблему 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

🤩 Свежее превью .NET Microsoft выпустила первую предварительную версию .NET 11 с улучшениями во всех областях: рантайм, SDK,
🤩 Свежее превью .NET Microsoft выпустила первую предварительную версию .NET 11 с улучшениями во всех областях: рантайм, SDK, библиотеки, C#, ASP.NET Core, Blazor и .NET MAUI. ➡️ Библиотеки • Поддержка Zstandard compression для эффективного сжатия • BFloat16 — новый тип с плавающей точкой для ML-сценариев • Улучшения ZipArchiveEntry для работы с архивами • FrozenDictionary теперь поддерживает collection expressions ➡️ API и утилиты: • Расширенная поддержка Rune в String, StringBuilder и TextWriter • MediaTypeMap для определения MIME-типов • API верификации HMAC и KMAC • Создание жёстких ссылок • DivisionRounding для режимов целочисленного деления • Happy Eyeballs в Socket.ConnectAsync для быстрого подключения по IPv4/IPv6 ➡️ Рантайм • Runtime Async — улучшенная асинхронность на уровне рантайма • CoreCLR на WebAssembly — полноценный рантайм в браузере • Расширение интерпретатора • JIT-оптимизации производительности • GC Heap Hard Limit для 32-битных процессов • Поддержка архитектур RISC-V и s390x ➡️ SDKdotnet run теперь интерактивно выбирает целевой фреймворк и устройство • dotnet test поддерживает позиционные аргументы • dotnet watch — горячая перезагрузка для изменений в ссылках и настраиваемые порты ➡️ C# и F# • C#: передача коллекций как аргументов • C# расширенная поддержка раскладки памяти • F#: параллельная компиляция включена по умолчанию, ускорение компиляции вычислительных выражений, новые флаги --disableLanguageFeature и --typecheck-only для FSI. ➡️ Блог разработчиков 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #async_news

🧑‍💻 Закон Хайрама: почему вы не можете изменить свой API Формулировка закона: При достаточном количестве пользователей API
🧑‍💻 Закон Хайрама: почему вы не можете изменить свой API Формулировка закона:
При достаточном количестве пользователей API не имеет значения, что вы обещаете в контракте — все наблюдаемое поведение вашей системы станет чьей-то зависимостью.
Вы создали API. Написали документацию. Явно указали, что гарантируете, а что нет. Но пользователи будут полагаться не только на задокументированное поведение, но и на: • Порядок элементов в ответе • Формат временных меток • Текст сообщений об ошибках • Время отклика • Недокументированные эндпоинты • Побочные эффекты • Баги И любое изменение этого может сломать чей-то прод. Excel и ошибка 1900 года В ранних версиях Excel был баг: 1900 год считался високосным, но таковым не являлся. Пользователи создали сложные таблицы, которые зависели от этого неправильного вычисления. Microsoft не мог просто исправить баг — это сломало бы тысячи таблиц. Ошибка сохранялась до Excel 2003. Даже сейчас есть опция «Enable iterative calculation» для совместимости. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

⭐️ SQL Server в одном файле LocalDB — это SQL Server в одном .mdf файле. Идеально для тестов, локальной разработки и инструментов. Создаётся одной командой, не требует установки сервера. LocalDB — это облегчённая версия SQL Server, которая: работает в режиме пользователя, то есть без сервиса, хранит базу в одном .mdf файле, ведёт себя как настоящий SQL Server и не требует установки полноценного SQL Server. Минимальный рабочий пример:
using Microsoft.Data.SqlClient;
using System.IO;

const string DatabaseName = "TestDatabase";
var databasePath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
    "MyApp", "Data"
);

// Создаём директорию если её нет
if (!Directory.Exists(databasePath))
{
    Directory.CreateDirectory(databasePath);
}

var dataFile = Path.Combine(databasePath, $"{DatabaseName}.mdf");
var logFile = Path.Combine(databasePath, $"{DatabaseName}_log.ldf");

// Безопасное экранирование для SQL
var escapedDbName = DatabaseName.Replace("]", "]]");
var escapedDataPath = dataFile.Replace("'", "''");
var escapedLogPath = logFile.Replace("'", "''");

var masterConnection = new SqlConnectionStringBuilder
{
    DataSource = @"(localdb)\MSSQLLocalDB",
    InitialCatalog = "master",
    IntegratedSecurity = true,
    TrustServerCertificate = true
}.ConnectionString;

var createDbQuery = $"""
    IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'{escapedDbName}')
    BEGIN
        CREATE DATABASE [{escapedDbName}]
        ON PRIMARY (
            NAME = N'{escapedDbName}',
            FILENAME = N'{escapedDataPath}'
        )
        LOG ON (
            NAME = N'{escapedDbName}_log',
            FILENAME = N'{escapedLogPath}'
        )
        COLLATE Latin1_General_100_CI_AI_SC_UTF8;
    END
    """;

using var conn = new SqlConnection(masterConnection);
await conn.OpenAsync();

using var cmd = new SqlCommand(createDbQuery, conn);
await cmd.ExecuteNonQueryAsync();

Console.WriteLine($"База данных создана: {dataFile}");
Будут созданы необходимые файлы и база будет готова принимать подключения. Создание идемпотентное — повторный запуск безопасен. LocalDB работает под текущим пользователем Windows: • Папка должна быть доступна на запись • Не нужны права администратора • Файлы принадлежат пользователю Пакет: Microsoft.Data.SqlClient Требует: LocalDB. Он входит в Visual Studio или SQL Server Express. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

👀 Смотрим видео про URL Работайте с API каждый день, но часто ли задумываетесь, как правильно строить эндпоинты. В видео под
👀 Смотрим видео про URL Работайте с API каждый день, но часто ли задумываетесь, как правильно строить эндпоинты. В видео подробно про пагинацию, query-параметры, фильтры, сортировки, поддомены, порты и пути с версионированием. ➡️ Подтянуть базу про URL 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #il_люминатор

👍 Модификатор protected internal В C# модификатор доступа protected internal открывает доступ к полю, методу или свойству из двух зон. Любые классы внутри той же сборки могут обращаться к такому члену напрямую. Наследники базового класса получают доступ, даже если они в другой сборке. Пример:
public class BaseClass
{
    protected internal int SecretValue = 42;
}
Protected internal оказывается самым широким среди комбинированных, кроме public. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека шарписта #sharp_view

🟥 Утечки данных в .NET-приложениях чаще происходят не из-за хакеров, а из-за неверной работы с ключами, конфигурациями и базовой криптографией. Ошибки на уровне кода быстро превращаются в инциденты. На открытом уроке разберём практическое применение System.Security.Cryptography: AES, RSA, хеширование и цифровые подписи. Поговорим о безопасном хранении и передаче секретов, управлении ключами и принципе наименьших привилегий. ❗️ Вы системно разберёте уязвимости OWASP Top-10 для .NET: инъекции, небезопасную десериализацию, XSS, CSRF — и способы их нейтрализации на уровне кода и архитектуры. Отдельно обсудим шифрование данных в БД, защиту строк подключения и безопасное логирование без утечек токенов. 🟥Встречаемся 10 февраля в 20:00 МСК в преддверии старта курса «C# Developer. Professional». Зарегистрируйтесь, чтобы не пропустить: https://clc.to/UzMt9g Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

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