Библиотека шарписта | C#, F#, .NET, ASP.NET
Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Show more📈 Analytical overview of Telegram channel Библиотека шарписта | C#, F#, .NET, ASP.NET
Channel Библиотека шарписта | C#, F#, .NET, ASP.NET (@csharpproglib) in the Russian language segment is an active participant. Currently, the community unites 21 866 subscribers, ranking 6 212 in the Technologies & Applications category and 30 851 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 21 866 subscribers.
According to the latest data from 10 June, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -87 over the last 30 days and by -4 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 12.06%. Within the first 24 hours after publication, content typically collects 7.04% reactions from the total number of subscribers.
- Post reach: On average, each post receives 2 638 views. Within the first day, a publication typically gains 1 540 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 8.
- Thematic interests: Content is focused on key topics such as .net, шарписта, навигация, await, string.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Все самое полезное для C#-разработчика в одном канале.
По рекламе: @proglib_adv
Учиться у нас: https://proglib.io/w/b60af5a4
Для обратной связи: @proglibrary_feeedback_bot
РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead”
Thanks to the high frequency of updates (latest data received on 11 June, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
ToLookup — это метод LINQ, который группирует элементы коллекции по ключу. Похож на GroupBy, но есть важные отличия, которые делают его удобным в определённых ситуациях.
— Как работает ToLookup
Метод создаёт структуру данных ILookup<TKey, TElement> — это неизменяемая коллекция групп. Каждая группа содержит элементы с одинаковым ключом.
var users = new[]
{
new { Name = "Anna", Department = "Dev" },
new { Name = "Boris", Department = "Dev" },
new { Name = "Clara", Department = "QA" }
};
var lookup = users.ToLookup(u => u.Department);
foreach (var user in lookup["Dev"])
{
Console.WriteLine(user.Name); // Anna, Boris
}
Обращение к группе происходит через индексатор lookup["Dev"]. Если ключа нет — вернётся пустая последовательность, а не исключение.
— ToLookup vs GroupBy
GroupBy возвращает IEnumerable<IGrouping<TKey, TElement>> — это отложенное выполнение. Группировка происходит при каждой итерации.
ToLookup выполняется немедленно и возвращает готовую структуру в памяти. Это значит:
• Данные группируются один раз при вызове метода
• Повторные обращения к группам не пересчитывают результат
• Потребляет память под всю структуру сразу
— Когда использовать ToLookup
Подходит, если вам нужно:
+ Многократно обращаться к одним и тем же группам
+ Избежать повторных вычислений группировки
+ Получать пустые последовательности вместо исключений для отсутствующих ключей
+ Неизменяемую структуру данных
Не подходит, если:
- Данные большие и в памяти не поместятся
- Нужна отложенная обработка
- Группировка нужна один раз — тогда GroupBy эффективнее
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_viewWHERE archived_at IS NULL. Индексы раздуваются. Миграции данных становятся сложнее — надо ли обрабатывать записи двухлетней давности? Всегда есть риск, что архивные данные случайно попадут туда, где их быть не должно.
Создание записи затрагивает внешние системы. Восстановление может требовать сложной логики, которая всегда будет неполной копией API создания. Старые данные могут не пройти новые правила валидации.
Альтернативные подходы
• Архивирование на уровне приложения
При удалении записи приложение отправляет событие в очередь, а отдельный сервис сохраняет архивные данные в другом месте.
Плюсы: основная БД остаётся простой, удаление асинхронное (быстрее и надёжнее), данные можно сериализовать в удобном формате.
Минусы: легко допустить баг и потерять архивные данные, больше инфраструктуры, сложнее искать записи для восстановления.
• Триггеры PostgreSQL
Создаём универсальную таблицу archive, которая хранит JSON-представление удалённых записей:
CREATE TABLE archive (
id UUID PRIMARY KEY,
table_name TEXT NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL,
archived_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Триггер автоматически копирует удаляемую строку в архив. Можно даже отслеживать каскадные удаления через session variables.
• Реплика без DELETE
Держать логическую реплику, которая игнорирует DELETE-запросы или превращает их в archived_at.
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#il_люминаторRAG для ответов по внутренней документации;
— фреймворки уровня LangChain и LlamaIndex в Enterprise-среде;
— работа с хранилищами векторных эмбеддингов (FAISS, Chroma).
📅 Когда: 23.01 в 19:00 МСК
Узнать подробностиdotnet tool. После запуска Stryker анализирует код, создаёт мутантов и прогоняет по ним тесты. В отчёте вы видите:
• Какие мутации выжили
• Mutation Score — процент убитых мутантов
• Конкретные строки кода, где тесты слабые
Практический пример
Допустим, у вас метод проверяет возраст пользователя. Stryker меняет age >= 18 на age > 18. Если тест с граничным значением 18 отсутствует — мутант выживает, и вы понимаете, где дописать проверку.
Stryker умеет работать с xUnit, NUnit, MSTest. Настраивается через JSON-файл, где можно указать пороговые значения mutation score, исключить файлы из анализа, настроить уровни логирования.
Процесс требует времени — каждая мутация прогоняет весь набор тестов. Но результат того стоит: вы находите слепые зоны в тестовом покрытии, которые обычный coverage не показывает.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#il_люминаторFreeSpire.XLS и Newtonsoft.Json. Первая читает .xlsx без зависимостей, вторая формирует JSON.
Код начинается с загрузки файла в поток. Библиотека преобразует лист в DataSet, где строки становятся объектами. Первая строка служит заголовками полей.
Чтение и конвертация данных:
using Spire.Xls;
using Newtonsoft.Json;
Workbook wb = new Workbook();
wb.LoadFromFile("данные.xlsx");
DataTable таблица = wb.Worksheets.ExportDataTable();
JsonSerializerSettings опции = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore
};
string результат = JsonConvert.SerializeObject(таблица, опции);
File.WriteAllText("выход.json", результат);
Игнорируйте null для компактности. Форматируйте даты единообразно. Тестируйте на реальных данных — библиотека FreeSpire.XLS ограничена объемом, но достаточна для большинства случаев.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_view[Benchmark]
[Arguments(42)]
public int SumWithOffset(int offset)
{
Func<int, int> addOffset = value => value + offset;
return ApplyTwice(addOffset, offset);
}
В старой версии платформы такой код почти гарантировал лишнюю аллокацию делегата и замыкания в куче.
По сути JIT делает за разработчика ту оптимизацию которую раньше приходилось реализовывать вручную через отказ от лямбд и делегатов на горячем пути.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#il_люминатор// Было
for (int i = 0; i < 1000; i++)
{
ProcessImage(images[i]);
}
// Стало
Parallel.For(0, 1000, i =>
{
ProcessImage(images[i]);
});
Вот и всё. Task Parallel Library сам распределит работу по потокам, сам управляет ThreadPool, сам балансирует нагрузку.
Когда это имеет смысл:
+ Обработка изображений, видео
+ Математические вычисления
+ Парсинг больших объёмов данных
+ Криптографические операции
Не подходит:
- Обработка меньше 100 элементов
- Операции с базой данных или API
- Быстрые операции вроде i * 2
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_viewInclude(), он генерирует один огромный SQL-запрос с множеством JOIN. Результат? Тысячи дублирующихся строк, гигабайты трафика и медленная работа.
Пример:
var posts = await context.Posts
.Include(p => p.Comments)
.ThenInclude(c => c.Reactions)
.ToListAsync();
При 100 постах, у каждого по 10 комментариев, в каждом по 10 реакций — вместо 11 100 записей получаем результирующий набор на 10 000 строк.
Добавьте .AsSplitQuery() — и EF Core разобьёт один большой запрос на несколько маленьких:
var posts = await context.Posts
.AsSplitQuery() // ← магия здесь
.Include(p => p.Comments)
.ThenInclude(c => c.Reactions)
.ToListAsync();
Query Splitting — это не хак и не костыль. Это правильный способ работы с EF Core в read-heavy сценариях.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#il_люминаторpublic const Price = OldPrice; // до 20.01
Мы меняем значение константы: завтра обучение станет дороже. Успейте пробросить заказ сегодня, чтобы зафиксировать текущую стоимость в своём стеке.
Инициализировать рост компетенций{
var value = dictionary[key];
Process(value);
}
catch (KeyNotFoundException)
{
// ignore
}
Отсутствие ключа в словаре — это не исключительная ситуация. Это ожидаемый сценарий. Использование exceptions в таких случаях передаёт неправильный смысл и усложняет отладку, когда происходят настоящие ошибки.
Правильный подход — явное ветвление:
if (dictionary.TryGetValue(key, out var value))
{
Process(value);
}
Этот код читается понятно, работает быстрее и сохраняет исключения значимыми.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_viewswitch внутри сервиса разные варианты выносятся в отдельные классы с общим интерфейсом, а контекст просто делегирует работу выбранной реализации.
Типовая схема такая. Есть интерфейс Strategy, есть несколько конкретных стратегий, и есть контекст, который держит ссылку на стратегию и вызывает ее метод, не зная деталей реализации. Это снижает связность и позволяет добавлять новые варианты без переписывания старого кода.
Мини пример на C#:
public interface IDiscountStrategy
{
decimal Apply(decimal total);
}
public sealed class RegularDiscount : IDiscountStrategy
{
public decimal Apply(decimal total) => total;
}
public sealed class VipDiscount : IDiscountStrategy
{
public decimal Apply(decimal total) => total * 0.9m;
}
public sealed class Checkout
{
private readonly IDiscountStrategy _discount;
public Checkout(IDiscountStrategy discount) => _discount = discount;
public decimal TotalWithDiscount(decimal total) => _discount.Apply(total);
}
Если стратегия выбирается по условиям, условие должно выбирать объект, а не ветку кода:
var checkout = serviceProvider.GetRequiredService<Checkout>();
var total = checkout.TotalWithDiscount(100m);
Выбор стратегии лучше делать на границе приложения, например в фабрике или при конфигурации через DI, потому что прямое создание зависимостей внутри сервиса жестко привязывает код к конкретной реализации.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_view.NET разработчика архитектура и алгоритмы — это база. Если вы хотите проектировать сложные системы или внедрять ИИ в свои энтерпрайз-решения, сейчас лучший момент для старта.
В Proglib Academy поднимаются цены. Успейте забрать курс по старой стоимости:
— Разработка ИИ-агентов
— Математика для разработки AI-моделей
— ML для старта в Data Science
— Математика для Data Science
— Специалист по ИИ
— Алгоритмы и структуры данных
— Программирование на Python
— Основы IT для непрограммистов
— Архитектуры и шаблоны проектирования
Забрать по старой цене
⚠️ Повышение уже 19 январяvar allItems = orders
.SelectMany(o => o.Items)
.Where(i => i.IsActive)
.ToList();
Цикл часто дает больше ясности и предсказуемости:
var allItems = new List<Item>();
foreach (var order in orders)
{
foreach (var item in order.Items)
{
if (!item.IsActive)
continue;
allItems.Add(item);
}
}
Плюс тут легко вставить break, continue, счетчики, ограничения, и не гадать как они сложатся с отложенным выполнением.
📍 Навигация: Вакансии • Задачи • Собесы
🐸Библиотека шарписта
#sharp_view
Available now! Telegram Research 2025 — the year's key insights 
