🧑💻 Неявная проверка на 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
Senior .NET Engineer — до 450 000₽ с удалёнкой.
C# разработчик на удалёнку с ЗП до 250 000 ₽
C#/.NET-разработчик — удалёнка.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤖 Миграция с GitHub
Если следите за IT-комьюнити, то наверняка замечали: всё больше программистов переезжают с GitHub. Недавно оттуда мигрировали язык программирования Zig и инструмент Leiningen, а за ними — сотни индивидуальных разработчиков.
В чём проблема
• GitHub стал хуже технически
После покупки Microsoft в 2018 платформа деградирует: интерфейс грузится дольше, GitHub Actions запускает джобы случайно и сам интерфейс раздут до безобразия.
• Copilot — это плагиат
GitHub Copilot буквально выдаёт куски кода дословно. Это нарушение лицензий и воровство чужого кода. Software Freedom Conservancy (те, кто поддерживают Wine, Git, QEMU) организовали кампанию «Give Up GitHub» именно из-за этого.
• Закрытая платформа для открытого кода
Парадокс: серверная часть GitHub — проприетарный софт. Вы размещаете open-source проекты на закрытой платформе, которую контролирует Microsoft.
В отличие от Instagram или Twitter, GitHub не контролирует дистрибуцию контента. Уход с GitHub — это небольшая неудобство для контрибьюторов, но не исчезновение из поля зрения.
Куда переезжать
Бесплатно и с хостингом:
• Codeberg (Forgejo) — некоммерческий проект, для FOSS
• SourceHut — платно $4-12/мес, но есть финпомощь
• GitLab — бесплатный тариф с ограничениями
Самохостинг:
• Gitea — простой и лёгкий
• Gogs — ещё проще
• Gerrit — если нужен продвинутый code review
Децентрализация:
• Radicle — p2p git
• Или просто свой скрипт, заливающий в S3
💬 Где вы держите свои проекты?
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#entry_point
Если следите за IT-комьюнити, то наверняка замечали: всё больше программистов переезжают с GitHub. Недавно оттуда мигрировали язык программирования Zig и инструмент Leiningen, а за ними — сотни индивидуальных разработчиков.
В чём проблема
• GitHub стал хуже технически
После покупки Microsoft в 2018 платформа деградирует: интерфейс грузится дольше, GitHub Actions запускает джобы случайно и сам интерфейс раздут до безобразия.
• Copilot — это плагиат
GitHub Copilot буквально выдаёт куски кода дословно. Это нарушение лицензий и воровство чужого кода. Software Freedom Conservancy (те, кто поддерживают Wine, Git, QEMU) организовали кампанию «Give Up GitHub» именно из-за этого.
• Закрытая платформа для открытого кода
Парадокс: серверная часть GitHub — проприетарный софт. Вы размещаете open-source проекты на закрытой платформе, которую контролирует Microsoft.
В отличие от Instagram или Twitter, GitHub не контролирует дистрибуцию контента. Уход с GitHub — это небольшая неудобство для контрибьюторов, но не исчезновение из поля зрения.
Куда переезжать
Бесплатно и с хостингом:
• Codeberg (Forgejo) — некоммерческий проект, для FOSS
• SourceHut — платно $4-12/мес, но есть финпомощь
• GitLab — бесплатный тариф с ограничениями
Самохостинг:
• Gitea — простой и лёгкий
• Gogs — ещё проще
• Gerrit — если нужен продвинутый code review
Децентрализация:
• Radicle — p2p git
• Или просто свой скрипт, заливающий в S3
💬 Где вы держите свои проекты?
📍 Навигация: Вакансии • Задачи • Собесы
#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9😁7👍4
☝️ Не повторяйтесь
Принцип DRY (Don't Repeat Yourself) — один из самых известных в программировании. Но, как и любой принцип, его можно применять неправильно. Давайте разберёмся, когда следовать DRY, а когда от него отступить.
Признаки over-DRYing
• Функция с 5+ параметрами:
• Generic Repository:
Когда дублирование правильно
• Случайное совпадение:
• Разные контексты:
Повторите код три раза, прежде чем рефакторить:
Первый раз — пишите
Второй раз — терпите
Третий раз — рефакторьте
Дублирование в тестах — нормально:
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Принцип DRY (Don't Repeat Yourself) — один из самых известных в программировании. Но, как и любой принцип, его можно применять неправильно. Давайте разберёмся, когда следовать DRY, а когда от него отступить.
Признаки over-DRYing
• Функция с 5+ параметрами:
// Универсальная функция-монстр
public async Task<object> FetchDataAsync(
string entityType, int? id, string filter,
int pageSize, bool includeDeleted, params string[] includes) { }
// Специализированные методы
public async Task<List<User>> GetActiveUsersAsync(int page, int pageSize)
=> await _context.Users.Where(u => u.IsActive)
.Skip(page * pageSize).Take(pageSize).ToListAsync();
• Generic Repository:
// Кажется умным, но бесполезен
public interface IRepository<T> where T : class
{
Task<T> GetByIdAsync(int id);
Task<IEnumerable<T>> GetAllAsync();
}
// Специфичный и полезный
public interface IUserRepository
{
Task<User> GetByEmailAsync(string email);
Task<User> GetWithOrdersAsync(int id);
}
Когда дублирование правильно
• Случайное совпадение:
// НЕ объединяйте! Разные бизнес-концепции
public string FormatUserName(User u) => $"{u.FirstName} {u.LastName}";
public string FormatProductName(Product p) => $"{p.Brand} {p.Model}";
• Разные контексты:
// UI: простая проверка
public bool ValidateEmail(string email) => email.Contains("@");
// API: строгая проверка
public bool ValidateEmail(string email) =>
Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");
Повторите код три раза, прежде чем рефакторить:
Первый раз — пишите
Второй раз — терпите
Третий раз — рефакторьте
Дублирование в тестах — нормально:
[Fact]
public void CreateUser_ShouldSucceed()
{
var user = new User { Name = "Alice", Age = 25 };
Assert.Equal("Alice", _service.CreateUser(user).Name);
}
[Fact]
public void UpdateUser_ShouldSucceed()
{
var user = new User { Name = "Alice", Age = 25 }; // OK
// Читаемость важнее DRY
}
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔10👍6❤2😁1
Microsoft выпустили разбор про то, как работать с AI в .NET. Если вы думали, что интеграция LLM — это боль и каша из разных SDK, вот хорошие новости.
Microsoft.Extensions.AI — один API для всех
Работаете с OpenAI — один SDK. Решили попробовать Ollama — другой API. Захотели Azure OpenAI — третий подход. Microsoft решили эту проблему радикально: один интерфейс для всех провайдеров.
IChatClient client = ...; // любой провайдер
await foreach (var update in client.GetStreamingResponseAsync("How are you?"))
{
Console.Write(update);
}
Раньше, чтобы получить структурированный JSON, нужно было плясать с бубном и JSON Schema. Теперь:
record Family(List<Person> Parents, List<Person>? Children);
record Person(string Name, int Age);
var family = await client.GetResponseAsync<Family>(
[
new ChatMessage(ChatRole.System, "You are an AI assistant..."),
new ChatMessage(ChatRole.User, "Create a family with 2 parents...")
]);
Схему сгенерируют за вас, JSON распарсят, десериализуют.
Хотите отправить фото для анализа? Обойдёмся без сотни строк:
var image = new DataContent(File.ReadAllBytes(@"photo.jpg"), "image/jpeg");
var messages = new List<ChatMessage>
{
new(ChatRole.System, "You are a photo analyst..."),
new(ChatRole.User, [prompt, image])
};
record ImageAnalysis(string Description, string[] Tags);
var analysis = await client.GetResponseAsync<ImageAnalysis>(messages);
Работает с изображениями, аудио и видео.
Один API, middleware, типизация, телеметрия. Можно не изобретать велосипед при каждой смене провайдера.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍38
Вы написали отличную заметку в Markdown в Obsidian, Notion или обычном редакторе, а теперь нужно отправить её коллеге или начальнику в Google Docs.
Копируете текст и... все форматирование слетает. Заголовки превращаются в решётки ###, списки ломаются, код выглядит убого.
Решение: md2cb
Простая утилита, которая конвертирует ваш Markdown в богатый HTML и кладёт в буфер обмена. Просто:
cat заметка.md | md2cb
# Ctrl+V в любое приложение
Есть флаг -e для быстрого редактирования:
md2cb -e # открывает $EDITOR, конвертирует после сохранения
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Что такое абстракция в ООП?
Звучит просто, но можно запутаться между абстракцией, интерфейсами и абстрактными классами.
Ключевое слово здесь — упрощение. Абстракция —
Всё остальное — несущественные детали.
📍 Навигация: Вакансии • Задачи • Собесы
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Архитектура ИИ-агентов: учим матчасть
Пока Microsoft развивает Semantic Kernel, индустрия стандартизирует паттерны на Python. Курс «Разработка ИИ-агентов» поможет понять принципы построения таких систем, независимо от вашего основного языка.
Что в программе:
— графовая оркестрация (
— работа с памятью и контекстом (RAG);
— мультиагентные протоколы.
Кодим на Python (нужны базовые знания), но полученные архитектурные скиллы универсальны. Первая лекция уже доступна.
Смотреть лекцию
Записаться на курс
Пока Microsoft развивает Semantic Kernel, индустрия стандартизирует паттерны на Python. Курс «Разработка ИИ-агентов» поможет понять принципы построения таких систем, независимо от вашего основного языка.
Что в программе:
— графовая оркестрация (
LangGraph);— работа с памятью и контекстом (RAG);
— мультиагентные протоколы.
Кодим на Python (нужны базовые знания), но полученные архитектурные скиллы универсальны. Первая лекция уже доступна.
Смотреть лекцию
Записаться на курс
🔥1
Разработчик запустил в продакшн своё веб-приложение для управления временем — The Coffee Timer. Проект реализует технику Pomodoro с кофейной эстетикой.
Приложение предлагает классический таймер Pomodoro с 25-минутными рабочими сессиями и визуализацией в виде анимированной кофейной чашки.
Бэк построен на .NET, фронт —React + TypeScript + Tailwind CSS. В качестве базы данных используется Supabase.
Хороший пример современного full-stack проекта с использованием .NET.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1