fa
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

نمایش بیشتر

📈 تحلیل کانال تلگرام Библиотека шарписта | C#, F#, .NET, ASP.NET

کانال Библиотека шарписта | C#, F#, .NET, ASP.NET (@csharpproglib) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 21 707 مشترک است و جایگاه 5 962 را در دسته فناوری و برنامه‌ها و رتبه 30 301 را در منطقه روسيا دارد.

📊 شاخص‌های مخاطب و پویایی

از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 21 707 مشترک جذب کرده است.

بر اساس آخرین داده‌ها در تاریخ 27 اوت, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -42 و در ۲۴ ساعت گذشته برابر 3 بوده و همچنان دسترسی گسترده‌ای حفظ شده است.

  • وضعیت تأیید: تأیید نشده
  • نرخ تعامل (ER): میانگین تعامل مخاطب 15.91% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 7.92% واکنش نسبت به کل مشترکان کسب می‌کند.
  • دسترسی پست‌ها: هر پست به طور میانگین 3 454 بازدید دریافت می‌کند. در اولین روز معمولاً 1 718 بازدید جمع‌آوری می‌شود.
  • واکنش‌ها و تعامل: مخاطبان به‌طور فعال حمایت می‌کنند؛ میانگین واکنش به هر پست 26 است.
  • علایق موضوعی: محتوا بر موضوعات کلیدی مانند .net, шарписта, навигация, await, string تمرکز دارد.

📝 توضیح و سیاست محتوایی

نویسنده این فضا را محل بیان دیدگاه‌های شخصی توصیف می‌کند:
Все самое полезное для C#-разработчика в одном канале. Наши курсы: https://clc.to/y3LDtw По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

به لطف به‌روزرسانی‌های پرتکرار (آخرین داده در تاریخ 28 اوت, 2026)، کانال همواره به‌روز و دارای دسترسی بالاست. تحلیل‌ها نشان می‌دهد مخاطبان به‌طور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامه‌ها تبدیل کرده‌اند.

21 707
مشترکین
+324 ساعت
-137 روز
-4230 روز
آرشیو پست ها
🔄 Дайджест недели Коротко про события недели. — 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

⚡️ 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