C# Portal | Программирование – Telegram
C# Portal | Программирование
14.9K subscribers
965 photos
118 videos
24 files
808 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Связь: @devmangx

РКН: https://clck.ru/3FocB6
Download Telegram
Новая C#-библиотека RCParsing, которая предлагает гибридный подход к обработке сложных синтаксисов с отступами.

Разработчики отмечают, что традиционные инструменты часто не справляются с такими задачами, а использование барьерных токенов значительно улучшает качество парсинга. В качестве примера приводится разбор YAML.

Подробнее в статье

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Тонкое, но мощное дополнение в C# 14:

(которое снизит количество NullReferenceException)

Null-conditional assignment (null-условное присваивание).

Этот оператор позволяет присвоить значение члену или элементу объекта только в том случае, если сам объект не равен null.

Это небольшое изменение, но оно может сильно повлиять на читаемость и безопасность кода.

Почему это полезно:

Убирает повторяющиеся проверки на null перед присваиванием.

Упрощает код, делая его легче для понимания.

Безопасно пропускает присваивание, если целевой объект равен null, тем самым избегая NullReferenceException.

См. пример кода

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥29❤‍🔥73👍1
Лучший редактор изображений

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
😁23🔥5👏4❤‍🔥1🏆1
image_2025-09-30_07-04-26.png
868.3 KB
Какая единственная стратегия сильнее всего помогает улучшить производительность приложения?

Это — кешировать (почти) всё!

Кеш хранит копии часто используемых данных в быстродоступном месте, сокращая время доступа и снижая нагрузку на основные источники данных.

Преимущества кеширования:

- более быстрое получение данных
- снижение нагрузки на основные хранилища
- улучшение пользовательского опыта

Не ограничивайся только кешированием запросов к базе данных, ведь чтение из кеша гораздо быстрее, чем вызов API.

Как решить, что кешировать?

Лучше спросить себя: а почему бы это не закешировать?

Добавление кеша имеет свою цену, поэтому для каждого кандидата нужно оценить:

- будет ли доступ через кеш быстрее
- стоит ли хранить эти данные
- как часто нужно валидировать
- сколько обращений придётся на одну запись в кеше
- локальный или общий кеш нужен

Нужно помнить, что данные в кеше могут устаревать, и бывают ситуации, когда кеширование неуместно.

Чтобы оценить эффективность кеша, можно отслеживать метрики, например cache misses.

Популярные стратегии кеширования:

🔸Cache-Aside
Приложение само управляет чтением и записью в кеш. При cache miss данные берутся из основного хранилища и добавляются в кеш.

🔸Read-Through
При cache miss кеш автоматически подгружает данные из основного хранилища. Это упрощает работу, так как кеш сам обрабатывает промахи.

🔸Write-Around
Данные пишутся напрямую в основное хранилище, минуя кеш. Полезно, когда записи происходят часто, а чтения — реже.

🔸Write-Back
Сначала данные пишутся в кеш, а позже синхронизируются с основным хранилищем. Снижает количество операций записи, но есть риск потери данных, если синхронизация не успеет выполниться.

🔸Write-Through
Данные одновременно записываются и в кеш, и в основное хранилище. Обеспечивает консистентность, но может увеличивать задержку записи. Подходит там, где критична целостность данных.


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍3❤‍🔥2
Как проще всего запускать фоновые задачи в .NET?

Фоновые задачи — это процессы или операции, которые выполняются независимо от основного потока выполнения программы или приложения.

Обычно такие задачи работают в фоне, часто без прямого взаимодействия с пользователем, и могут выполнять различные функции, например:

отправка уведомлений

периодические задачи

задачи по расписанию

обработка сообщений

асинхронная обработка

обработка данных в реальном времени


Для этого в .NET можно использовать IHostedService.

Он содержит два метода:

- StartAsync
- StopAsync

Мы можем добавить в него нужное действие, достаточно зарегистрировать этот сервис в Program и всё будет готово.

Такой подход подходит для простых фоновых задач. Для более продвинутых сценариев можно использовать следующие NuGet-пакеты:

- Hangfire
- Quartz

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍113
Вышла онлайн IDE для .NET

Теперь приложения на C# и XAML можно писать прямо в браузере. 👨‍💻

IDE работает на WebAssembly, поддерживает drag-and-drop UI, сохранение проектов в облако или на ПК и компиляцию через Roslyn прямо в клиенте.

Запуск выполняется в отдельном iframe, чтобы интерфейс не подвисал, а в планах - автодополнение кода, AI-ассистент и шэринг проектов.

Попробовать можно на xaml.io

подробнее — Habr

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👎116👍5🤔2
Примеры полнотекстового поиска в Entity Framework:

Если ваша СУБД поддерживает эту возможность и вам действительно нужен поиск с подстановочными символами, рассмотрите использование полнотекстового поиска для более эффективных запросов.

// Полнотекстовый поиск по связанным терминам и словоформам  
// (например, "climate change", "climatic changes").
var resultsFreeText = context
.Articles
.Where(a => EF.Functions.FreeText(a.Content, "climate change")).ToList();


// Полнотекстовый поиск с операторами (AND, OR, NEAR) для точного совпадения фразы.
var resultsContains = context
.Articles
.Where(a => EF.Functions.Contains(a.Content, "climate change")).ToList();


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍65
Как на самом деле выполняется C#-код?

1. Вы пишете .cs-файл.

2. Компилятор (Roslyn) преобразует его в IL (Intermediate Language — промежуточный язык).

3. IL сохраняется в сборках (.dll / .exe).

Во время выполнения CLR :

- загружает сборки,

- проверяет IL на безопасность,

- компилирует «горячие» участки кода в машинные инструкции через JIT-компилятор.

CLR также обеспечивает сборку мусора, управление памятью и доступ к базовой библиотеке классов (System.*).

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

Понимание этого пайплайна помогает при отладке проблем с производительностью, работе с зависимостями из NuGet и выборе между JIT- и AOT-компиляцией.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍255
This media is not supported in your browser
VIEW IN TELEGRAM
На GitHub есть репозиторий free-programming-books, где собрано более 4000 бесплатных книг, 2000 курсов и других полезных ресурсов по программированию

Для удобства поиска можно использовать этот инструмент

Этот проект - яркий пример силы опенсорс сообщества, который из клона списка со StackOverflow стал одним из самых популярных на GitHub ✌️

Русскоязычная версия ресурсов

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍103
Одна из самых недооценённых фич в .NET — System.Threading.Channels.

С её помощью можно просто построить асинхронное взаимодействие через сообщения на C#. У Channel есть два API:

- для записи сообщений в канал,

- для асинхронного чтения сообщений из канала.

Можно запустить воркер в фоне, который будет забирать сообщения и передавать их на обработку. На этой основе легко собрать примитивный in-memory message bus (со всеми очевидными ограничениями).

Пример реализации тут

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍103
Как упаковать RPM на Linux через GitLab CI/CD?

В материале детально разбирается разработка службы на .NET Core, конфигурация spec-файла, применение макросов и запуск GitLab Runner внутри Docker. Полезные рекомендации для DevOps по автоматизации билда и контролю версий.

Читать подробнее: https://habr.com/ru/articles/952748/

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2
Чистим NuGet и освобождаем десятки гигабайт

Со временем NuGet накапливает огромные объёмы кэша:

- http-cache может весить 10+ ГБ

- global-packages легко разрастается до 50 ГБ и больше

Если места на диске не хватает — кэши можно безопасно почистить:

Очистка глобальных пакетов:

dotnet nuget locals global-packages --clear


Очистка http-кэша:

dotnet nuget locals http-cache --clear


Очистка временных файлов:

dotnet nuget locals temp --clear


Полная зачистка всего:

dotnet nuget locals all --clear


После очистки пакеты будут скачаны заново при следующем dotnet restore, но на диске станет намного свободнее.

Проверить текущие кэши можно так:

dotnet nuget locals all --list


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥25👍75
Python vs C#

Два языка — две совершенно разные цепочки выполнения:

C# (.NET Runtime):

🔹Исходный код → Intermediate Language (IL) → сборки (.dll / .exe)
🔹Сборки проверяются и загружаются в .NET Runtime
🔹JIT- или AOT-компилятор переводит IL в машинный код
🔹Мощные инструменты и статическая типизация делают выполнение предсказуемым и быстрым

Python (CPython Runtime):

🔸Исходный код → байткод (кэшируется в .pyc, если возможно)
🔸Система импорта подгружает модули и зависимости во время выполнения
🔸Python Virtual Machine (PVM) интерпретирует байткод “на лету”
🔸Гибкий и динамичный язык, но скорость зависит от накладных расходов интерпретации

Баланс очевиден:

• C# оптимизирован под производительность и безопасность
• Python — под гибкость и скорость итераций

Разные подходы, разные сильные стороны, именно поэтому оба языка процветают в своих экосистемах.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍125🤣3🔥2
Одна из частых проблем у многих программистов — они используют async и await, не понимая, что на самом деле происходит.

Асинхронная задача не блокирует основной поток, поэтому пока выполняется длительная операция, мы можем выполнять другие действия.

Console.WriteLine("Запуск программы");

// начинаем загрузку файла, длительность — 3 секунды
var downloadFileTask = DownloadFile();

// основной поток не блокируется — можем выполнять другие задачи
Console.WriteLine("Делаем другие вещи: обращаемся к БД, отправляем письма и т.д.");

// на этом этапе ожидаем завершения загрузки файла
await downloadFileTask;

Console.WriteLine("Программа завершена");

async Task DownloadFile()
{
Console.WriteLine("Загружаем файл...");
await Task.Delay(3000); // симулируем ожидание 3 секунды
Console.WriteLine("Файл загружен!");
}


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
8🤯5👍3🍌2
This media is not supported in your browser
VIEW IN TELEGRAM
MauiReactor — MVU для .NET MAUI

Открытая библиотека, реализующая паттерн Model View Update для .NET MAUI.

Она упрощает разработку кроссплатформенных приложений, ускоряет hot reload и повышает производительность.

MauiReactor предлагает альтернативу XAML и позволяет описывать интерфейс на C#. Поддерживаются темы, условный рендеринг и интеграция сторонних компонентов.

Подробнее

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍73🤔1
Если у нас есть List<T> и IList<T>, то перебор элементов через List<T> выполняется быстрее, чем через IList<T>. Почему так происходит?

[MemoryDiagnoser]
public class Benchmark
{
private readonly List<int> numbersList = Enumerable.Range(0, 10_000).ToList();
private readonly IList<int> numbersIList = Enumerable.Range(0, 10_000).ToList();

[Benchmark(Baseline = true)]
public int GetSumOfList()
{
var sum = 0;
foreach (var number in numbersList) { sum += number; }
return sum;
}

[Benchmark]
public int GetSumOfIList()
{
var sum = 0;
foreach (var number in numbersIList) { sum += number; }
return sum;
}
}


Результаты:

Метод         Среднее    Ошибка    Ст.откл.   Отн.  Отн.откл.  Память  Отн.память
------------- ---------- --------- ---------- ----- ---------- ------- ----------
GetSumOfList 4.214 μs 0.0836 μs 0.0782 μs 1.00 0.03 - NA
GetSumOfIList 19.508 μs 0.0459 μs 0.0384 μs 4.63 0.08 40 B NA


Откуда берутся эти 40 байт?

Когда вызывается List<T>.GetEnumerator() (а это происходит при каждой итерации foreach), возвращается структура под названием Enumerator.

Но при вызове IList<T>.GetEnumerator() возвращается переменная типа IEnumerator, которая содержит упакованную (boxed) версию этого перечислителя.

Вот откуда появляются дополнительные 40 байт аллокации и часть потери производительности.

Виртуальные вызовы методов

Есть и второй фактор.

При вызове IList<T>.GetEnumerator() вызывается виртуальный метод, а это медленнее, чем вызов невиртуального метода.

Причина проста: во время выполнения CLR должно определить, какой конкретный тип реально используется, и уже потом вызвать нужную реализацию метода.

В случае с List<T> этого делать не нужно — тип уже известен, и вызов идёт напрямую, без дополнительной диспетчеризации.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍11🤯6🥴1
Получение информации о .NET Runtime в приложении

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥9👍43
Этот пост вряд ли принесёт вам практическую пользу в повседневной жизни, ну, разве что улыбку. Давайте доведём ValueTuple до крайности ⌨️

Тип ValueTuple это удобный синтаксический сахар. Например, если у вас есть такой код, даже если вы назвали элементы кортежа:

(var one, var two) = MyFunc();
Console.WriteLine(one + two);

(int ANumber, int AnotherNumber)
MyFunc() => (1,2);


Компилятор сгенерирует следующее:

[CompilerGenerated]
internal class Program
{
private static void <Main>$(string[] args)
{
ValueTuple<int, int> valueTuple = <<Main>$>g__MyFunc|0_0();
int item = valueTuple.Item1;
int item2 = valueTuple.Item2;
Console.WriteLine(item + item2);
}

[CompilerGenerated]
[return: TupleElementNames(new string[] { "ANumber", "AnotherNumber" })]
internal static ValueTuple<int, int> <<Main>$>g__MyFunc|0_0()
{
return new ValueTuple<int, int>(1, 2);
}
}


То есть компилятор создаёт список Item1, Item2 и так далее для всех элементов кортежа. Но интересный момент возникает, если элементов больше 7:

var (a,b,c,d,e,f,g,h) = MyFunc();
Console.WriteLine(a + b + c + d + e + f + g + h);

(int a, int b, int c, int d, int e, int f, int g, int h) MyFunc()
=> (1,2,3,4,5,6,7,8);


Компилятор «понизит» это до:

ValueTuple<int, int, int, int, int, int, int, ValueTuple<int>> valueTuple = <<Main>$>g__MyFunc|0_0();
int item = valueTuple.Item1;
int item2 = valueTuple.Item2;
int item3 = valueTuple.Item3;
int item4 = valueTuple.Item4;
int item5 = valueTuple.Item5;
int item6 = valueTuple.Item6;
int item7 = valueTuple.Item7;
int item8 = valueTuple.Rest.Item1;
Console.WriteLine(item + item2 + item3 + item4 + item5 + item6 + item7 + item8);


После седьмого элемента компилятор создаёт новое свойство Rest, которое содержит «остальные» элементы. Если переборщить, например так:

(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,  int k, int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z, int aa, int bb, int cc, int dd, int ee, int ff, int gg, int hh, int ii, int jj, int kk, int ll, int mm, int nn, int oo, int pp, int qq, int rr, int ss, int tt, int uu, int vv, int ww, int xx) MyFunc()
{
return (1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50);
}


И использовать так:

var (a,b,c,....xx) = MyFunc();


То получится что-то вроде valueTuple.Rest.Rest.Rest.Rest.Item1

Если хотите поиграться с этим: sharplab.io

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯114👍4😁1
Rider 2025.2.3 был выпущен

Узнать об изменениях в этой сборке и скачать обновление можно здесь:

https://blog.jetbrains.com/dotnet/2025/10/06/resharper-and-rider-2025-2-3/

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72
Соглашения об именовании в C#

Согласны или нет?

Константы — в SCREAMING_CASE с подчёркиваниями

Поля экземпляра — в camelCase с префиксом подчёркивания

Статические поля — в PascalCase

Свойства — в PascalCase

Локальные переменные — в camelCase

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
💯21🤯84👍3