C# Ready | Unity
10.1K subscribers
1.2K photos
62 videos
553 links
Авторский канал по разработке на C# и Unity.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Автор: @energy_it

РКН: https://clck.ru/3SBaT3

Реклама на бирже: https://telega.in/c/csharp_ready
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
☕️ ByteHide Blog — C# Clean Code & Tips!

Блог про C# и .NET с упором на чистый и поддерживаемый код: практичные гайды, подборки сниппетов, разбор современных фич (C# 12, .NET 10, атрибуты, паттерны), плюс статьи для прокачки от уровня новичка до мидла.

📌 Оставляю ссылочку: bytehide.com

➡️ C# Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥5👍4
🔥15👍85
Как упростить работу с индексами и подстроками?

Классический подход — вечные Substring и ручные вычисления длины. В итоге получаем выражения, которые трудно читать и легко сломать:
var lastChar = input[input.Length - 1];
var withoutLast = input.Substring(0, input.Length - 1);


Чем больше таких мест, тем больше “магических чисел” и арифметики над Length, особенно при работе с расширениями файлов, префиксами и хвостами строк.

С индексами (^) и диапазонами (..) в C# можно писать это намного компактнее и ближе к тому, как мы думаем о строке:
var lastChar = input[^1];    // последний символ
var withoutLast = input[..^1]; // всё, кроме последнего


Здесь ^1 — “первый элемент с конца”, [..^1] — “с начала до элемента перед последним”. Для хвостов и расширений тоже получается читаемое правило: [^3..] — последние три символа, [..^4] — всё, кроме последних четырёх.

🔥 Итог: меньше Substring, меньше ручных Length - 1, код читается как работа с отрезками строки, а не как арифметика с индексами.

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
13🔥8👍6
Прогресс-бар в консоли для долгих операций — наглядный прогресс без UI!

Когда операция выполняется несколько секунд (или минут), пустая консоль выглядит как зависшая. Проще сразу показывать прогресс — например, в виде текстового прогресс-бара.

Нам хватит стандартных пространств имён:
using System;
using System.Threading;


Сделаем простой пример: у нас есть «долгая» операция из 100 шагов. В цикле будем имитировать работу через Thread.Sleep и обновлять строку прогресса:
int total = 100;

for (int i = 0; i <= total; i++)
{
DrawProgressBar(i, total);
Thread.Sleep(50); // имитация долгой работы
}

Console.WriteLine();
Console.WriteLine("Готово!");


Вся магия в методе DrawProgressBar: он считает процент, строит строку вида [#####-----] 50% и перерисовывает одну и ту же строку в консоли:
static void DrawProgressBar(int current, int total)
{
int width = 30; // ширина прогресс-бара в символах

double progress = (double)current / total;
int filled = (int)(progress * width);

string bar = new string('#', filled) + new string('-', width - filled);

Console.Write($"\r[{bar}] {progress:P0}");
}


Ключевой момент — \r в начале строки:
он возвращает курсор в начало текущей строки, поэтому новый вывод перезаписывает старую строку прогресса, а не переносит консоль вниз.

В итоге во время работы программы ты увидишь динамически меняющуюся строку:
[###############---------------] 50%


и по завершении — Готово!.

🔥 Главное — вынести отрисовку прогресса в отдельный метод и обновлять одну строку через \r, тогда консоль не превратится в простыню из сотен сообщений.

➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍169🔥5😁2
👩‍💻 Сколько времени прошло на самом деле?

Переведём сухие числа разницы во времени в живые фразы, чтобы «через час» и «три дня назад» звучали естественно и не требовали пересчёта.

В этой задаче узнаешь:

Как почувствовать разницу между датами, а не числами;

Где естественно сказать «назад», а где «через»;

Почему короткая фраза о времени понятнее таймера.


Когда интерфейс говорит с человеком человеческим языком, время перестаёт быть абстракцией. Пусть твои даты звучат как живые истории, а не скучные отметки в протоколе.

➡️ C# Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍85🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
☕️ CodeAbbey — тренажёр алгоритмического мышления!

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

📌 Оставляю ссылочку: codeabbey.com

➡️ C# Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥117👍4
Как убрать 10 одинаковых using в каждом файле?

В проектах быстро появляется “шапка”, которая копируется из файла в файл: System, Linq, коллекции, логирование, общие неймспейсы фреймворка. Полезного кода ещё нет, а сверху уже простыня.
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
// + ещё 5–10 строк...


В C# 10 можно вынести общие using в один файл и сделать их глобальными — тогда они автоматически применяются ко всему проекту:
// GlobalUsings.cs
global using System;
global using System.Linq;


🔥 Итог: файлы становятся чище, меньше копипасты, меньше “шума” в каждом классе. Главное правило — выноси в global только то, что реально используется повсеместно (иначе можно получить лишние конфликты имён и путаницу).

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥117😁2🤝1
👩‍💻 Сортируем LINQ без сюрпризов!

В этой шпаргалке — понятная разница между обычной и вторичной сортировкой, когда уместен Reverse(), и как задавать свой порядок сравнения без лишней путаницы.

➡️ C# Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍11🤝8
☕️ Нашел вам разбор ConfigureAwait без мифов — когда он нужен, а когда нет!

В этой статье:
• Что делает SynchronizationContext и почему это важно для await
• Когда ConfigureAwait(false) даёт пользу, а когда ломает логику
• Особые случаи: IAsyncEnumerable, библиотеки и “контекстные” приложения

🔊 Продолжай читать на Habr!


➡️ C# Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍6🔥3😁2
Retry с Polly — переживаем временные ошибки без ручных try/catch!

Иногда внешний API или сервис отвечает ошибкой (500, timeout), но при повторной попытке всё работает. Оборачивать каждый запрос в try/catch и писать циклы — неудобно. Проще использовать Polly и задать политику повторных попыток.

Сначала подключим нужные пакеты и пространства имён:
using System;
using System.Net.Http;
using Polly;
using Polly.Retry;


Создадим политику retry: при ошибке запроса пробуем ещё 3 раза с паузой в 1 секунду:
RetryPolicy retryPolicy = Policy
.Handle<HttpRequestException>()
.WaitAndRetry(
retryCount: 3,
sleepDurationProvider: _ => TimeSpan.FromSeconds(1),
onRetry: (exception, timeSpan, retryCount, context) =>
{
Console.WriteLine($"Повтор #{retryCount} через {timeSpan.TotalSeconds} сек...");
});


Теперь используем эту политику при выполнении HTTP-запроса:
string GetDataWithRetry()
{
return retryPolicy.Execute(() =>
{
Console.WriteLine("Делаем запрос...");
return CallUnstableService();
});
}


Для примера сделаем простую «заглушку» нестабильного сервиса:
int attempt = 0;

string CallUnstableService()
{
attempt++;

if (attempt < 3)
throw new HttpRequestException("Сервис временно недоступен");

return "Данные успешно получены";
}


Теперь посмотрим, как это работает:
Console.WriteLine(GetDataWithRetry());


Возможный вывод в консоли:
Делаем запрос...
Повтор #1 через 1 сек...
Делаем запрос...
Повтор #2 через 1 сек...
Делаем запрос...
Данные успешно получены


🔥 Обрати внимание: код запроса остался чистым — Polly сам управляет повторами и задержками, без лишних try/catch.

➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥7👍6
Как не ловить NullReferenceException в цепочках user.Profile.Address.City?

Когда данные приходят из API/БД/ввода пользователя — в любой момент может прилететь null. И вместо простого чтения свойства появляется лес из проверок:
string city;

if (user != null &&
user.Profile != null &&
user.Profile.Address != null &&
user.Profile.Address.City != null)
{
city = user.Profile.Address.City;
}
else
{
city = "Не указан";
}


С null-conditional оператором ?. и значением по умолчанию через ?? то же самое пишется коротко и читаемо:
var city = user?.Profile?.Address?.City ?? "Не указан";


?. работает как “безопасная точка”: если слева null — выражение дальше не падает и возвращает null.
А ?? подставляет значение, если результат оказался null.

🔥 Итог: меньше шума, меньше ручных проверок, меньше шансов словить NullReferenceException. Код читается как правило: «если чего-то нет — подставь дефолт».

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍95
Разница между out и ref — когда что использовать?

В C# оба ключевых слова позволяют передавать параметры по ссылке, но работают они по-разному. Из-за этого их часто путают — особенно на собеседованиях.

Разберёмся на простом и наглядном примере.

Создадим метод с параметром ref. В этом случае переменная обязана быть инициализирована до вызова метода:
void Increment(ref int number)
{
number++;
}


Используем его:
int value = 5;
Increment(ref value);
Console.WriteLine(value);


Вывод в консоли:
6


Теперь сделаем похожий метод, но уже с out. Здесь метод обязан присвоить значение параметру внутри себя:
void CreateValue(out int number)
{
number = 10;
}


Вызовем его — обратите внимание, что переменную заранее инициализировать не нужно:
int result;
CreateValue(out result);
Console.WriteLine(result);


Результат:
10


🔥 Главное различие:
ref — работает с уже существующим значением
out — используется, когда метод создаёт значение и возвращает его через параметр

➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍188🔥6