ValueTask часто хвалят за экономию памяти. Но если использовать его в публичном API, потребители могут не оценить такой шаг.
Вопрос: чем так плох ValueTask в публичном API? Он же снизит аллокации
Ответ:
📍 Навигация: Вакансии • Задачи • Собесы
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3😢1
🎯 Нестандартные форматы резюме
Листайте карточки и подбирайте вариант резюме под свои навыки. В комментах можете поделиться своими проектами 👇
➡️ В статье ещё два формата
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
Листайте карточки и подбирайте вариант резюме под свои навыки. В комментах можете поделиться своими проектами 👇
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😁7👍5🤔2
LangGraph vs Semantic Kernel: архитектура агентов
В .NET мире популярен Semantic Kernel, но индустрия движется к графовым подходам.
Архитектурные преимущества:
— цикличность: нативная поддержка циклов (ReAct pattern);
— state management: управление контекстом похоже на работу с сессиями;
— human-in-the-loop: возможность поставить граф на паузу, получить апрув человека и продолжить.
Курс по архитектуре уже стартовал.
Записаться на курс
Смотреть первую лекцию бесплатно
В .NET мире популярен Semantic Kernel, но индустрия движется к графовым подходам.
LangGraph реализует паттерн, где агент — это не просто цепочка плагинов, а граф с состоянием.Архитектурные преимущества:
— цикличность: нативная поддержка циклов (ReAct pattern);
— state management: управление контекстом похоже на работу с сессиями;
— human-in-the-loop: возможность поставить граф на паузу, получить апрув человека и продолжить.
Курс по архитектуре уже стартовал.
Записаться на курс
Смотреть первую лекцию бесплатно
👍6❤1
В .NET для HTTP-запросов фабрика
IHttpClientFactory упрощает создание клиентов, интегрируется с DI и решает проблемы вроде утечек сокетов.Фабрика кэширует обработчики сообщений, управляет их временем жизни и добавляет логирование.
Зачем нужна фабрика
HttpClient из Framework 4.5 часто создают вручную, но это приводит к проблемам: сокеты не освобождаются, DNS не обновляется. Фабрика решает это через пул обработчиков с лайфтаймом в 2 минуты по умолчанию.
Она регистрируется через
AddHttpClient в IServiceCollection и дает доступ к CreateClient. Короткоживущие клиенты подходят для большинства случаев, в отличие от долгоживущих с PooledConnectionLifetime.Предупреждение: если нужны куки, лучше обойтись без фабрики из-за шаринга
CookieContainer.Способы использования
Разработчики выбирают между базовым, именованными, типизированными клиентами или сгенерированными через Refit.
В базовом варианте инжектят
IHttpClientFactory и вызывают CreateClient для каждого запроса. Это просто для рефакторинга старого кода.Именованные клиенты настраивают по имени из конфига, с базовым URI и заголовками вроде User-Agent:
builder.Services.AddHttpClient("MyClient", client =>
{
client.BaseAddress = new Uri("https://api.example.com/");
client.DefaultRequestHeaders.UserAgent.ParseAdd("MyApp");
});Затем
CreateClient("MyClient").Типизированные удобны для конкретного API: класс принимает
HttpClient в конструкторе, фабрика регистрирует его через AddHttpClient<T>.Логика запросов инкапсулируется в методах класса, DI все подхватывает. IntelliSense работает, нет строковых ключей.
Не используйте в синглтонах: клиент должен быть короткоживущим, иначе DNS не обновится. Лучше именованные или SocketsHttpHandler:
public class ApiService(HttpClient client)
{
public async Task<Todo[]> GetTodos(int id) =>
await client.GetFromJsonAsync<Todo[]>($"todos/{id}");
}
В итоге фабрика делает HTTP-клиенты в .NET предсказуемыми и масштабируемыми. Для прода это как стандарт: меньше багов с соединениями, проще DI.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
🧑💻 Неявная проверка на null
В C# можно заставить любой класс вести себя в if как в JavaScript: просто if (myObject) и внутри проверка на null. Это работает благодаря перегрузке операторов.
Создайте класс с двумя статическими методами:
Теперь
Единственный минус: никто не ожидает такого, код становится загадкой для команды. Лучше стандартные
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
В C# можно заставить любой класс вести себя в if как в JavaScript: просто if (myObject) и внутри проверка на null. Это работает благодаря перегрузке операторов.
Создайте класс с двумя статическими методами:
public class User
{
public string Name { get; set; }
public static bool operator true(User? user) => user?.Name != null;
public static bool operator false(User? user) => user?.Name == null;
}
Теперь
if (user) сработает если имя задано, иначе попадет в else. Компилятор автоматически вызывает нужный оператор при булевом контексте.Единственный минус: никто не ожидает такого, код становится загадкой для команды. Лучше стандартные
is not null или !ReferenceEquals(null, obj).📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15😢12😁6🌚2
Класс
Random в .NET генерирует псевдослучайные числа для игр, тестов или симуляций. Он работает на основе сида, обычно времени, и дает целые, дробные значения или байты.Основы класса Random
System.Random создает последовательности чисел через алгоритм. Для простого инта берут Next(min, max), где верхняя граница не включается.Переиспользуйте один экземпляр, иначе в цикле из-за одинаковых сидов выйдут повторения. Статический или инжектированный через DI вариант подходит для прода:
var rng = new Random();
int число = rng.Next(1, 101); // от 1 до 100
NextDouble возвращает от 0.0 до 1.0, умножьте и сдвиньте для нужного интервала. Байты через NextBytes заполняют массив. Это для тестовых файлов или симуляций.double температура = rng.NextDouble() * 50 - 10; // от -10 до 40
byte[] буфер = new byte[16];
rng.NextBytes(буфер);
Обычный
Random не годится для токенов или паролей, предсказуем при известном сиде. Берите RandomNumberGenerator из System.Security.Cryptography для криптографии.GetInt32(1, 101) или Fill для байт. В API для ключей всегда крипто-вариант.Random не потокобезопасен, общий экземпляр сломается. ThreadLocal<Random> создаст по инстансу на поток. Parallel.For с ним работает корректно, без гонок:var локальныйRng = new ThreadLocal<Random>(() => new Random());
Parallel.For(0, 100, i => {
int значение = локальныйRng.Value!.Next(100);
});
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤5
📰 Дайджест недели
В .NET-среде штиль, новостей не так много, поэтому вспоминаем лучшее за неделю.
— IoT на .NET
— ExecuteUpdate и ExecuteDelete
— Коты вместо HTTP статусов
— 10 советов по обустройству вашего рабочего места
— Нестандартные форматы резюме
Делитесь в комментах своими инфоповодами недели 👇
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#async_news
В .NET-среде штиль, новостей не так много, поэтому вспоминаем лучшее за неделю.
— IoT на .NET
— ExecuteUpdate и ExecuteDelete
— Коты вместо HTTP статусов
— 10 советов по обустройству вашего рабочего места
— Нестандартные форматы резюме
Делитесь в комментах своими инфоповодами недели 👇
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Anonymous Poll
8%
Боксинг в C#
4%
Паттерны не для облаков
7%
История про DLQ в PostgreSQL
7%
IOT на .NET
9%
Docker для быстрого развёртывания
4%
ExecuteUpdate и ExecuteDelete
6%
Фича флаги в .NET
9%
Фабрика HttpClient
35%
JS-стиль в C#
12%
Генерация случайных чисел
🥱4👾2
Semantic Kernel или LangGraph?
В мире .NET популярен
Это позволяет реализовывать сложные паттерны: Human-in-the-loop (человек подтверждает действие), Time Travel (откат состояния назад) и цикличное планирование. Понимание этих принципов пригодится любому разработчику, внедряющему AI.
Записаться на курс
Погружение в архитектуру агентов: Смотрите вводный урок бесплатно.
В мире .NET популярен
Semantic Kernel, но глобальный стандарт задаёт LangGraph. Его киллер-фича — явное управление графом выполнения и состоянием (Stateful Graph).Это позволяет реализовывать сложные паттерны: Human-in-the-loop (человек подтверждает действие), Time Travel (откат состояния назад) и цикличное планирование. Понимание этих принципов пригодится любому разработчику, внедряющему AI.
Записаться на курс
Погружение в архитектуру агентов: Смотрите вводный урок бесплатно.
❤5🤔1
Инлайнинг (Inlining) — замена вызова метода его телом напрямую в месте вызова. JIT-компилятор делает это автоматически для маленьких методов, которые весят меньше 32 байт.
Зачем это делается
• Убирает overhead вызова метода
• Улучшает локальность кода
• Даёт прирост в 5-7 раз для горячих путей
Пример
Без инлайнинга:
public int Calculate(int a, int b)
{
return Add(a, b) * 2;
}
private int Add(int a, int b) // JIT заинлайнит автоматически
{
return a + b;
}
Что делает JIT:
public int Calculate(int a, int b)
{
return (a + b) * 2; // тело Add() вставлено напрямую
}
Принудительный инлайнинг:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int Multiply(int a, int b)
{
return a * b;
}
Не гадайте — профилируйте. Иногда JIT делает лучше без вашей помощи.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤7🤔1🌚1
🆚 Namespace vs Assembly
Давайте разберёмся, чем отличается namespace от assembly.
Namespace — это логическая организация кода.
Assembly — это физический файл на диске.
Они существуют в разных измерениях и решают разные задачи.
Namespace (пространство имён) — это способ логической группировки классов, интерфейсов и других типов, чтобы избежать конфликтов имён:
Зачем нужны namespace
• Без namespace два класса с именем Logger конфликтуют. С namespace можно иметь
• Организация кода по доменам:
• Упрощённое использование кода с using
Можно объявить namespace один раз для всего проекта:
Что такое Assembly
Assembly (сборка) — это скомпилированный физический файл на диске .dll или .exe, который содержит IL-код и метаданные.
•
•
Как они связаны
Подключение сборки:
Это добавляет assembly в проект.
Использование namespace:
Один работает на уровне файлов, другой — на уровне кода.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Давайте разберёмся, чем отличается namespace от assembly.
Namespace — это логическая организация кода.
Assembly — это физический файл на диске.
Они существуют в разных измерениях и решают разные задачи.
Namespace (пространство имён) — это способ логической группировки классов, интерфейсов и других типов, чтобы избежать конфликтов имён:
namespace MyCompany.PaymentSystem
{
public class PaymentProcessor
{
// ...
}
}
namespace MyCompany.Logging
{
public class Logger
{
// ...
}
}
Зачем нужны namespace
• Без namespace два класса с именем Logger конфликтуют. С namespace можно иметь
MyApp.Logger и ThirdPartyLib.Logger одновременно.• Организация кода по доменам:
MyCompany.Ecommerce.Orders, MyCompany.Ecommerce.Products, MyCompany.Ecommerce.Payments.• Упрощённое использование кода с using
using MyCompany.Ecommerce.Orders;
var order = new Order(); // Вместо: new MyCompany.Ecommerce.Orders.Order()
Можно объявить namespace один раз для всего проекта:
// GlobalUsings.cs
global using System;
global using MyCompany.Core;
Что такое Assembly
Assembly (сборка) — это скомпилированный физический файл на диске .dll или .exe, который содержит IL-код и метаданные.
•
.exe — приложение, которое можно запустить.•
.dll — библиотека для подключения.Как они связаны
Подключение сборки:
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
Это добавляет assembly в проект.
Использование namespace:
using Newtonsoft.Json; // Импортируем namespace
var json = JsonConvert.SerializeObject(obj);
//или без using
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
Один работает на уровне файлов, другой — на уровне кода.
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍8
🚀 Git v2.53
Вышла новая версия системы контроля версий Git v2.53. Разбираем ключевые изменения.
Новые команды
•
•
•
Улучшения существующих команд
•
•
•
И многие другие мелкие доработки.
➡️ Анонс
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#async_news
Вышла новая версия системы контроля версий Git v2.53. Разбираем ключевые изменения.
Новые команды
•
git maintenance is-needed — проверка, нужно ли выполнять задачи обслуживания репозитория.•
git repo info --all — показывает расширенную информацию о структуре репозитория.•
git blame --diff-algorithm=<algo> — теперь можно выбрать алгоритм сравнения при отслеживании изменений.Улучшения существующих команд
•
git replay — теперь выполняет обновление ссылок самостоятельно, не требуя дополнительных команд.•
git fast-import — новая опция --signed-commits=strip-if-invalid для удаления невалидных подписей.•
git apply и git diff — новый класс ошибок пробелов incomplete-line.И многие другие мелкие доработки.
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
Разберемся, как компилятор превращает понятный код в эффективный и почему лучше расписать «магическое число» на составляющие.
Самая простая оптимизация называется constant folding. Суть в том, что компилятор не будет заставлять процессор каждый раз высчитывать одно и то же. Если вы пишете
int result = 10 * 5 + 3 * 2, компилятор прекрасно понимает, что результат всегда будет 56, и именно это число окажется в скомпилированном коде.public void Example()
{
int result = 10 * 5 + 3 * 2; // Вы пишете это
// Компилятор превращает в:
int result = 56; // Уже посчитано
}
Более интересная оптимизация – constant propagation. Когда вы объявляете константу через const, компилятор запоминает её значение и подставляет его везде, где она используется.
public void ConstantPropagation()
{
const int multiplier = 100;
int value = 42;
int calculated = value * multiplier;
// Компилятор оптимизирует до:
int calculated = value * 100; // multiplier заменен значением
}
Оптимизация строк
С строками всё еще интереснее. Когда вы конкатенируете несколько строковых литералов, компилятор склеивает их в один. Код
string message = "Hello" + " " + "World"; превращается в string message = "Hello World";public void StringOptimization()
{
// Все литералы склеиваются в один
string message = "Hello" + " " + "World";
// Результат: string message = "Hello World";
// С константами тоже работает частично
const string greeting = "Hello";
string name = "Alice";
string message = greeting + " " + name;
// Результат: string message = "Hello " + name;
}
Используйте
const там, где это уместно, не бойтесь записывать формулы явно вместо магических чисел – компилятор сам посчитает результат.📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3🥱2
Вы ищете заказы там, где их ищут все. А локальный бизнес даже не знает о существовании биржи. ИП пишут в чатах «посоветуйте программиста» или листает Авито. Будьте там, где нет толпы.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰3❤2