Библиотека шарписта | C#, F#, .NET, ASP.NET
Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Больше📈 Аналитический обзор Telegram-канала Библиотека шарписта | C#, F#, .NET, ASP.NET
Канал Библиотека шарписта | C#, F#, .NET, ASP.NET (@csharpproglib) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 21 857 подписчиков, занимая 6 197 место в категории Технологии и приложения и 30 823 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 21 857 подписчиков.
Согласно последним данным от 12 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -48, а за последние 24 часа — -2, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 12.66%. В первые 24 часа после публикации контент обычно набирает 7.50% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 2 769 просмотров. В течение первых суток публикация набирает 1 640 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 9.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как .net, шарписта, навигация, await, string.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“Все самое полезное для C#-разработчика в одном канале.
По рекламе: @proglib_adv
Учиться у нас: https://proglib.io/w/b60af5a4
Для обратной связи: @proglibrary_feeedback_bot
РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead”
Благодаря высокой частоте обновлений (последние данные получены 13 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
var channel = Channel.CreateBounded<int>(5);
// producer
_ = Task.Run(async () =>
{
for (int i = 0; i < 10; i++)
{
await channel.Writer.WriteAsync(i);
Console.WriteLine($"Produced {i}");
}
channel.Writer.Complete();
});
// consumer
await foreach (var item in channel.Reader.ReadAllAsync())
{
Console.WriteLine($"Consumed {item}");
}
Почему это лучше, чем ConcurrentQueue? Потому что Channel создан сразу с учётом асинхронности. Вам не нужно городить блокировки и таймеры ожидания — достаточно написать await reader.ReadAsync(), и код будет сам по себе масштабироваться без блокировки потоков.
🐸Библиотека шарписта
#sharp_viewawait GetUser();
await GetOrders();
await GetRecommendations();
Каждая операция ждёт предыдущую и если каждый запрос занимает по секунде, общее время = 3 секунды.
А можно иначе:
var userTask = GetUser();
var ordersTask = GetOrders();
var recsTask = GetRecommendations();
await Task.WhenAll(userTask, ordersTask, recsTask);
Все задачи стартуют сразу. Теперь общее время = 1 секунда (ожидание самой длинной операции).
Маленький приём — большая разница во времени выполнения.
🐸Библиотека шарписта
#sharp_viewpublic record CreateOrderDto(string CustomerEmail, List<OrderItemDto> Items);
public class OrderApplicationValidator
{
public static void Validate(CreateOrderDto dto)
{
if (string.IsNullOrWhiteSpace(dto.CustomerEmail))
throw new ArgumentException("Email is required");
if (!dto.CustomerEmail.Contains("@"))
throw new ArgumentException("Email format is invalid");
if (dto.Items == null || dto.Items.Count == 0)
throw new ArgumentException("Order must contain at least one item");
}
}
Здесь мы проверяем только корректность ввода.
А вот внутри домена мы защищаем бизнес-правила:
public class OrderItem
{
public string ProductName { get; }
public int Quantity { get; }
public Money Price { get; }
private OrderItem(string productName, int quantity, Money price)
{
ProductName = productName;
Quantity = quantity;
Price = price;
}
public static OrderItem Create(string productName, int quantity, Money price)
{
if (string.IsNullOrWhiteSpace(productName))
throw new InvalidOperationException("Product name cannot be empty");
if (quantity <= 0)
throw new InvalidOperationException("Quantity must be greater than zero");
return new OrderItem(productName, quantity, price);
}
public Money GetTotal() => Money.Create(Quantity * Price.Amount);
}
Когда правила закреплены в домене, они становятся частью самой логики, а не зависимыми от внешних слоёв. Это гарантирует, что объект в принципе невозможно построить в некорректном виде.
🐸Библиотека шарписта
#il_люминаторdouble speed = 27.8;
вы пишете Speed speed = Speed.FromMetersPerSecond(27.8);
и работаете уже с километрами в час, милями или узлами — без ручных пересчётов.
В UnitsNet поддерживается более сотни единиц измерения — от времени и массы до температуры и силы. Вам не нужно держать в голове коэффициенты и вручную пересчитывать из одной системы в другую: библиотека сделает это сама.
Ещё один плюс — читаемость кода. Ваши расчёты выглядят как документация: сразу видно, где давление, где скорость, а где длина.
➡️ Попробовать либу
🐸Библиотека шарписта
#sharp_viewasync void ломает ваш код
В C# у async void есть дурная репутация, и не зря. Такой метод не возвращает Task, а значит, его нельзя await-ить, нельзя встроить в пайплайн и невозможно корректно отследить завершение.
Исключения из него не ловятся обычным образом — они пробиваются в синхронизационный контекст или в пул потоков, где легко превращаются в необработанные и могут уронить процесс.
// Контроллер ASP.NET Core
[HttpPost]
public async void Create() { await _svc.DoAsync(); } // Исключения мимо pipeline
// Библиотека
public async void SaveAsync(Item item) { await _repo.Save(item); } // Вызывающему не сконтролировать
Правильно — всегда возвращать Task:
[HttpPost]
public async Task<IActionResult> Create() { await _svc.DoAsync(); return Ok(); }
public Task Invoke(HttpContext ctx) => _next(ctx);
public Task SaveAsync(Item item) => _repo.Save(item);
Единственный сценарий, где async void уместен, — обработчики событий в UI-фреймворках вроде WPF или WinForms, где сигнатура задаётся самим фреймворком. Там приходится мириться, но даже там стоит ловить исключения локально и логировать их.
🐸Библиотека шарписта
#sharp_viewIReadOnlyList<T>. На первый взгляд, он обещает нам неизменяемый список. Но это полуправда.
Определение интерфейса:
public interface IReadOnlyList<out T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
{
T this[int index] { get; }
}
Интерфейс наследует IReadOnlyCollection, а тот, в свою очередь, наследует IEnumerable.
Таким образом, он даёт доступ: к элементам через индекс (this[int index]), к свойству Count, и к итерации через foreach.
⚠️ Важный нюанс: IReadOnlyList не делает коллекцию реально readonly.
Если у вас есть List<int> и вы приведёте его к IReadOnlyList<int>, изменять список по-прежнему можно — просто не через эту ссылку.
Пример:
var list = new List<int> { 1, 2, 3 };
IReadOnlyList<int> ro = list;
list.Add(4); // ro теперь "видит" 4
То есть IReadOnlyList — это контракт для чтения, а не гарантия неизменности.
Если нужна настоящая защита — используйте ImmutableArray или ReadOnlyCollection.
🐸Библиотека шарписта
#il_люминатор
Уже доступно! Исследование Telegram 2025 — ключевые инсайты года 
