Библиотека шарписта | C#, F#, .NET, ASP.NET
22.5K subscribers
2.44K photos
39 videos
85 files
4.64K links
Все самое полезное для C#-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Download Telegram
✏️ Задачка с собеса

Дано целое число, нужно проверить, является ли оно полным квадратом.

Первый рефлекс новичка — взять квадратный корень и проверить, целое ли число:
(int)Math.Sqrt(num) * (int)Math.Sqrt(num) == num


Но на собесе после этого последует вопрос: «А можете без встроенной функции?» Вот тогда начинается интересное.

Вместо математики используем логику: если x * x = num, то x находится где-то между 1 и num. Сужаем диапазон поиска, пока не найдём точный ответ.

public bool IsPerfectSquare(int num)
{
long left = 1;
long right = num;

while (left <= right)
{
long mid = (left + right) / 2;
long square = mid * mid;

if (square == num)
return true;
else if (square < num)
left = mid + 1;
else
right = mid - 1;
}

return false;
}


Есть ещё метод Ньютона для поиска корня — он даже быстрее для больших чисел:
public bool IsPerfectSquare(int num)
{
long x = num;

while (x * x > num)
{
x = (x + num / x) / 2;
}

return x * x == num;
}


Главное: объясните почему вы выбрали именно этот подход, а не просто скопировали решение. На собесе вас оценивают не только по скорости, а по способности мыслить.

➡️ Попробовать решить

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

#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82
👀 Управление доступом в .NET

Если вы работаете с авторизацией в .NET и используете Identity, но всё ещё не совсем понимаете, как правильно организовать систему разрешений — есть видео, которое стоит посмотреть.

В нём конкретный пример: как взять стандартный ASP.NET Core Identity и использовать его для управления доступом. Ничего экзотического — обычная setup с JWT и кастомным authorization handler.

➡️ Посмотреть видео

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

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
💬 Три дня работы

Завтра начнётся самая короткая рабочая неделя ноября. Это буквально понедельник, среда и пятница. После шестидневки самое то.

💬 Что будете делать? Успевать выполнить недельные обязанности за три дня? Или три дня будете пытаться начать работать?

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

#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡️ Пять команд .NET, без которых неудобно

Бывает, нужно быстро собрать, запустить или опубликовать проект без запуска тяжелой IDE, особенно в пайплайне или на сервере разработчика. Для этого хватает нескольких команд из .NET CLI, которые работают одинаково на всех платформах.

Проверить установку и окружение поможет команда dotnet --info, она покажет версии SDK и рантаймов и архитектуру хоста.

Сборка проекта выполняется командой dotnet build, по умолчанию в конфигурации Debug и с выводом артефактов в bin, причем команда учитывает инкрементальные изменения для скорости.

Запуск приложения через dotnet run объединяет сборку и старт процесса, что эквивалентно кнопке Run в IDE и удобно для ручных проверок локально.

Горячая перезагрузка из терминала через dotnet watch отслеживает изменения файлов и повторно запускает приложение с Hot Reload без ручного рестарта, что ускоряет цикл правка и проверка.

Если сборка ведет себя странно, стоит выполнить dotnet clean, чтобы удалить выходные артефакты и заставить следующий build собрать все заново.

Для развертывания используйте dotnet publish, который соберет релиз и положит готовый к деплою набор файлов в папку publish, включая веб приложения и сервисы.

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

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍1
🤨 Когда помощник становится врагом

Представьте, что вы отправили друга в магазин с деньгами на общий счёт. Он может потратить их на что угодно, при этом никому не отчитываясь. Вот примерно так же работает static с изменяемым состоянием. Удобно? Да. Безопасно? Совсем нет.

Почему static плохо сочетается с данными

Static — это ключевое слово, которое любят новички и используют для удобства. А потом из этого вырастают проблемы, которые отъедают часы отладки. Главная беда в том, что статические поля существуют всё время работы программы и доступны отовсюду.

Четыре золотых правила

1. Статические поля могут быть только для чтения. Лучше — константы.

2. Статические методы должны работать как математические функции: дали параметры — получили результат. Никаких побочных эффектов, никаких изменений состояния. Например: Select, Where, First из LINQ — это всё статические методы расширения, которые не трогают исходную последовательность.

3. Если в классе есть методы, которые не используют поля экземпляра, эту логику лучше вынести в отдельный статический класс-помощник. Это делает код чище, тесты проще.

4. Если вы создаёте статическое поле, пусть оно указывает на что-то, что не меняется. На объект конфигурации? Хорошо. На список данных, который вы потом модифицируете? Катастрофа.

Когда static — ваш друг

• Вспомогательные классы с чистыми функциями

Создайте статический класс StringUtils с методом static string ToPascalCase(string input). Нет состояния, нет побочных эффектов, нет проблем. Это хорошее использование.

• Методы расширения для преобразований

Select, Where и компания — статические методы расширения, которые берут данные, преобразуют их и возвращают новые. Функциональный подход, никакого волшебства.

• ThreadStatic для действительно отдельного состояния

Если каждому потоку нужно своё состояние, можно использовать ThreadStatic. Но даже здесь нужна осторожность — каждый поток всё равно должен управлять своим состоянием.

Передайте зависимость через конструктор, используйте DI-контейнер, создайте объект на сессию. Ваш будущий я, сидящий в отладчике в три утра, скажет вам спасибо.

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

#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
Гид по Redis в C# ASP.NET: ускоряем приложения и снижаем нагрузку на базу данных.

Redis — быстрая база данных в памяти, которая помогает масштабировать системы и ускорять доступ к данным. На открытом вебинаре курса OTUS C# ASP.NET Core разработчик Андрей Сорокин покажет, как интегрировать Redis в ASP.NET Core 8 и внедрить кэширование в реальных проектах.

📌 12 ноября, 20:00
Гид по Redis в C# ASP.NET
— настройка Redis в Docker
— кэширование ответов API
— хранение данных для быстрого доступа
— ускорение обработки запросов и снижение нагрузки на БД

Вебинар бесплатный и будет полезен C#-разработчикам, архитекторам и тимлидам, которые хотят повысить производительность приложений и упростить масштабирование.

👉 Регистрируйтесь: https://clc.to/YMHL9A

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

Представьте, что вы пришли в магазин и продавец говорит: «Вот вам что-то. Не знаю что. Может быть, помидоры, может быть, кирпич, может быть, счастье. Узнаете, когда вернётесь домой». Вот такое же ощущение от IActionResult без типов.

Проблема с IActionResult:
[HttpGet("{id:guid}")]
public async Task<IActionResult> GetById(Guid id, ISender mediator, CancellationToken ct)
{
var dto = await mediator.Send(new GetUserQuery(id), ct);
return dto is null ? NotFound() : Ok(dto);
}


Возвращаемый тип — IActionResult. Просто интерфейс. Ничего конкретного. Кто читает этот код, не знает, что именно вернётся. Может быть UserDto, может быть ошибка, может быть что угодно.

Вот так выглядит сгенерированная Swagger документация:
{
"responses": {
"200": { "description": "Success" }
}
}


Никакой информации о схеме. Кто использует ваш API, не знает, какие поля будут в ответе. IDE не может подсказать структуру. Тесты пишутся вслепую.

Решение: ActionResult<T>
[HttpGet("{id:guid}")]
public async Task<ActionResult<UserDto>> GetById(Guid id, ISender mediator, CancellationToken ct)
{
var dto = await mediator.Send(new GetUserQuery(id), ct);
return dto is null ? NotFound() : Ok(dto);
}


Возвращаемый тип — ActionResult<UserDto>. Конкретно и ясно. Читающий код понимает мгновенно: метод возвращает UserDto при успехе или ошибку. Swagger генератор видит типы и строит правильную документацию.

IActionResult можно использовать, когда метод не возвращает тело, к примеру ответ 204.

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

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍3
👨‍💻 Demystifier: когда стек-трейс не радует

Откройте логи ошибки из продакшена. Видите стек-трейс? Он полон <>c__DisplayClass2_0, d__5``1.MoveNext() и прочих артефактов, которые сгенерировал компилятор. Это не ошибка — это просто то, как .NET преобразует современный C# в IL. Но это делает поиск проблемы медленнее, чем нужно.

Demystifier восстанавливает оригинальный вид кода:

• Вместо ValueTuple``2 param показывает (string val, bool) param
• Вместо Func``1 показывает Func<string>
async методы помечает как async Task<string>
• Локальные функции и лямбды показывает с контекстом

Как применить

Вызовите exception.Demystify() и передайте результат:
try { /* ваш код */ }
catch (Exception ex)
{
logger.LogError(ex.Demystify(), "Ошибка");
}


Анализ стека стоит ресурсов. На высоконагруженной системе вызывать Demystify для каждого исключения неэкономно. Используйте его выборочно — для критических путей, для отладки в development окружении или для редких, но важных ошибок.

➡️ Репозиторий либы

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

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111
📎 Как считать повторения без условных операторов

Нужно посчитать, сколько раз каждое значение встречается в данных. Логично напрашивается проверка:
if (counts.ContainsKey(key))
counts[key]++;
else
counts[key] = 1;


Но есть способ проще:
counts[key] = counts.GetValueOrDefault(key) + 1;


Метод GetValueOrDefault возвращает значение, если ключ есть, или значение по умолчанию (для int это 0). Затем добавляем единицу. Никаких условных операторов, одна строка.

Если можете — используйте LINQ:
var counts = items.GroupBy(x => x.Key)
.ToDictionary(g => g.Key, g => g.Count());


Это явно показывает намерение: группируем по ключу, считаем количество в каждой группе.
Но если вы наполняете словарь в цикле или обрабатываете поток данных, GetValueOrDefault — идеальный выбор.

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

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
⭐️ Microsoft обновила дорожную карту в Visual Studio на ноябрь

Компания работает над несколькими направлениями, которые должны сделать IDE более интегрированной с AI.
Новые агенты для обработки сложных workflow, улучшения в режиме Agent Mode и Chat, а также поддержка работы нескольких агентов одновременно.

По части моделей Microsoft планирует добавить автоматический выбор модели в Chat, GPT-5 Codex, улучшить UX для устаревающих моделей и поддержку разных системных промптов для каждой модели.

Microsoft ставит цель сделать Copilot доступным на каждом этапе разработки — не только для написания кода, но и для поиска, исправления ошибок, написания тестов, коммитов.

➡️ Блог разработчиков

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

#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱76😁1
🤩 Lorem ipsum, который имитирует научный вздор

Представьте: нужно заполнить макет контентом, чтобы дизайнер видел, как всё выглядит. Берёте Lorem ipsum. Но он выглядит как набор слов. А если нужен текст, который с первого взгляда кажется серьезным, но при внимательном чтении — полная чушь? Вот для этого WaffleGenerator.

Это библиотека, которая генерирует абзацы в стиле научно-популярного бреда. Текст выглядит настоящим: правильная структура, логичные переходы, официальный тон. Но если вы прочитаете внимательно, поймёте, что там просто красивые слова без смысла.

Как применить

Просто:
var text = WaffleEngine.Html(paragraphs: 2, includeHeading: true);
var text = WaffleEngine.Text(paragraphs: 1, includeHeading: true);
var markdown = WaffleEngine.Markdown(paragraphs: 1, includeHeading: true);


Поддерживает три формата: HTML, обычный текст и Markdown.

➡️ Попробовать либу

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

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥74