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

Автор: @energy_c

РКН: https://clck.ru/3SBaT3
Download Telegram
👍8🔥32
Сидеть и работать в корпорации — страшно, жизнь-то мимо проходит. Уходить строить бизнес — страшно, а вдруг прогорит. Один из вариантов — разрабатывать свой пет-проект по вечерам. Многие успешные компании, например, Twitter, создавались именно так. Это не значит, что ваш проект обязательно заработает миллиарды, но заработать больше, чем в найме, и получить ценный опыт — вполне реально.

Перед началом разработки появляется множество вопросов, например:

• Как выбрать идею для пет-проекта?
• Что нужно знать про маркетинг
• Как запуститься и довести до первых продаж не имея бюджета на рекламу?

В телеграм-канале «Твой пет проект», Михаил Табунов делится своим опытом с разработчиками и менеджерами.

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

Подписывайтесь на «Твой пет проект», получайте пользу от практиков рынка!
https://t.me/+8Frwa03ciVlhNTky
Фильтруем пользователей по домену email через LINQ!

Допустим, у нас есть список пользователей, и нужно достать только email-адреса на gmail.com.
Создадим простую модель:
public record User(string Name, string Email);


Подготовим данные:
var users = new List<User>
{
new("Alex", "alex@gmail.com"),
new("Maria", "maria@company.com"),
new("Bob", "bob@gmail.com")
};


Можно пройтись циклом и вручную собрать результат:
var result = new List<string>();

foreach (var user in users)
{
if (user.Email.EndsWith("@gmail.com"))
{
result.Add(user.Email);
}
}


Но через LINQ это читается короче:
var result = users
.Select(user => user.Email)
.Where(email => email.EndsWith("@gmail.com"))
.ToList();


Select достаёт из пользователя только email.
Where оставляет адреса с нужным доменом.
В результате получим:
alex@gmail.com
bob@gmail.com


Такой подход удобно использовать для фильтрации клиентов, подписчиков, заявок, логов, доменов, тегов и любых списков объектов.
Если регистр может отличаться, лучше явно указать сравнение:
email.EndsWith(
"@gmail.com",
StringComparison.OrdinalIgnoreCase
)


Select() + Where() это удобная связка LINQ, когда нужно достать поле и отфильтровать его по условию.

➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍4🔥3
Напоминалка по исключениям в C#!

Например, NullReferenceException часто появляется при обращении к объекту, который равен null, а ArgumentNullException обычно используют, когда в метод передали обязательный аргумент без значения.

На картинке иерархия исключений в C#: Exception, SystemException, ApplicationException, ArgumentException, IOException и другие популярные типы ошибок.

Сохрани, чтобы не потерять!

➡️ C# Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75🔥3
Почему для времени события часто лучше DateTimeOffset, а не DateTime?

В C# часто пишут так:
var createdAt = DateTime.Now;


Но DateTime.Now зависит от локального времени сервера.

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

Для моментов времени чаще удобнее использовать:
var createdAt = DateTimeOffset.UtcNow;


DateTimeOffset хранит не только дату и время, но и смещение относительно UTC.

Это делает значение понятнее при логах, событиях, API, заказах, платежах и аудите.

А для отображения пользователю время уже можно переводить в его часовой пояс отдельно.

Для хранения момента события DateTimeOffset.UtcNow часто безопаснее, чем DateTime.Now.

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍126🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
👍 bookflow — полезные материалы для изучения различных языков!

На сайте собрана подборка полезных материалов для разработчиков, которые изучают C# и C++ и множество других языков. Здесь можно найти статьи, шпаргалки и обучающие ресурсы по основам синтаксиса, ООП, структурам данных, алгоритмам и ключевым концепциям разработки на этих языках.

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

➡️ C# Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍105🔥4
Напоминалка по pattern matching в C#!

Например, case string s проверяет тип и сразу даёт переменную, а FileInfo { Extension: ".html" } позволяет матчить объект по его свойствам.

На картинке основные виды pattern matching: type pattern, property pattern, positional pattern, relational pattern и null pattern.

Сохрани, чтобы не потерять!

➡️ C# Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍106🔥4
🤖 ChatGPT в твоих руках: от вопроса до результата за минуту

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

🤔 Но оформить подписку из России бывает непросто: нужны подходящий способ оплаты и дополнительные шаги.

😉 Не переживай, мы берём оформление на себя. Ты оформляешь заказ и предоставляешь необходимые данные, а мы активируем подписку за 5–15 минут. Иностранная карта и взаимодействие с платёжной системой OpenAI не потребуются.


💳 Оплата российской картой или через СБП
⚡️ Активация в течение 5–15 минут после получения необходимых данных
🔒 Поддержка на весь срок подписки и помощь при возникновении вопросов
⭐️ Более 3 лет опыта и 15 000+ выполненных заказов


😎 Оформи заказ и начни пользоваться ChatGPT уже сегодня!

💡 Также помогаем с оформлением других AI-подписок (Claude, Gemini и т.д.).

👉 ChatGPT Store
👎5😁1
Считаем количество заказов по статусам через LINQ!

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

Создадим простую модель:
public record Order(string Status, decimal Amount);


Подготовим данные:
var orders = new List<Order>
{
new("Paid", 1200m),
new("New", 500m),
new("Paid", 300m),
new("Cancelled", 100m)
};


Можно вручную обновлять словарь:
var result = new Dictionary<string, int>();

foreach (var order in orders)
{
if (!result.ContainsKey(order.Status))
{
result[order.Status] = 0;
}

result[order.Status]++;
}


Но через LINQ это выглядит компактнее:
var result = orders
.GroupBy(order => order.Status)
.ToDictionary(g => g.Key, g => g.Count());


GroupBy() собирает заказы в группы по статусу.

ToDictionary() превращает эти группы в словарь, где ключ это статус, а значение это количество заказов.

Результат будет примерно таким:

Paid      -> 2
New -> 1
Cancelled -> 1


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


➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍5🔥5
👩‍💻 Сегодня рассмотрим Channel<T> — безопасная асинхронная очередь задач в .NET

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

Что важно знать:

Работает без ручных блокировок и сложных синхронных вызовов.

Позволяет автоматически замедлять отправку при перегрузке памяти.

Обеспечивает плавную передачу данных между параллельными задачами.


Так вы получаете готовый «из коробки» механизм асинхронной очереди с естественным управлением нагрузкой без лишнего кода.

C# Ready | #гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥53👍2
FirstOrDefault() может вернуть null!

В C# часто ищут элемент в коллекции через LINQ:
var user = users.FirstOrDefault(u => u.Id == id);


Если пользователь найден то всё хорошо.

Но если подходящего элемента нет, FirstOrDefault() вернёт значение по умолчанию.

Для ссылочных типов это обычно:
null


Поэтому такой код может упасть:
Console.WriteLine(user.Name);


Если user оказался null, получим NullReferenceException.

Лучше явно обработать отсутствие результата:
var user = users.FirstOrDefault(u => u.Id == id);

if (user is null)
{
return;
}


Или выбросить понятную ошибку:
var user = users.FirstOrDefault(u => u.Id == id)
?? throw new InvalidOperationException("User not found");


Это особенно важно в API, сервисах, обработчиках команд и бизнес-логике.

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍9🔥4
Почему технические строки не стоит сравнивать через ToLower()?

Для проверки логина, роли или кода часто пишут так:

if (role.ToLower() == "admin")
{
GrantAccess();
}


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

Для обычного текста это может быть полезно. Но логины, роли, ключи конфигурации, HTTP-заголовки и другие технические значения обычно должны сравниваться по стабильным правилам, независимо от языка системы.

Для этого лучше явно указать тип сравнения:

if (string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase))
{
GrantAccess();
}


OrdinalIgnoreCase не создаёт промежуточную строку и выполняет регистронезависимое порядковое сравнение. Поведение не изменится после запуска приложения на сервере с другой локалью.

Если же сравнивается текст для пользователя, например названия или элементы поиска, может понадобиться CurrentCultureIgnoreCase.

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍86🔥4
Теперь небольшую программу на C# можно запустить прямо из одного файла!

В этой статье:

• Как работают File-Based Apps в .NET 10
• Как запустить .cs-файл без создания отдельного проекта
• Каким способом подключать NuGet-пакеты и дополнительные настройки
• Когда такой формат удобен для скриптов, автоматизации и быстрых экспериментов

Получается знакомая простота скриптовых языков, но с возможностями C# и всей экосистемой .NET.

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


➡️ C# Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍65
Почему технические строки не стоит сравнивать через ToLower()?

Для проверки логина, роли или кода часто пишут так:

if (role.ToLower() == "admin")
{
GrantAccess();
}


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

Для обычного текста это может быть полезно. Но логины, роли, ключи конфигурации, HTTP-заголовки и другие технические значения обычно должны сравниваться по стабильным правилам, независимо от языка системы.

Для этого лучше явно указать тип сравнения:

if (string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase))
{
GrantAccess();
}


OrdinalIgnoreCase не создаёт промежуточную строку и выполняет регистронезависимое порядковое сравнение. Поведение не изменится после запуска приложения на сервере с другой локалью.

Если же сравнивается текст для пользователя, например названия или элементы поиска, может понадобиться CurrentCultureIgnoreCase.

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍64🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
❤️‍🔥"Это разъ*бный сетап, бро!" 😤

Так сказал мой друг из Африки, когда увидел этот стол)
Не знаю уж че за сетап, меня зовут Саша и качественную необычную мебель из натурального дерева я делаю уже больше 12-ти лет, столько же занимаюсь и темой здоровья.

Когда я услышал, что до 10% смертности связано с сидячим образом жизни, меня это поразило и я задался целью делать максимально функциональные и полезные рабочие пространства, ибо геморрой в 30 это конечно довольно нишево, но все же сомнительно 😂

Ну а собрать такой комплект под свои задачи и при этом сразу прикинуть цены вы можете в удобном Mini App конструкторе
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥1
Отправляем несколько HTTP-запросов параллельно на C#!

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

Создадим HttpClient:
using var client = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10)
};


Запустим три запроса без немедленного ожидания результата:
Task<string> usersTask =
client.GetStringAsync(usersUrl);

Task<string> ordersTask =
client.GetStringAsync(ordersUrl);

Task<string> ratesTask =
client.GetStringAsync(ratesUrl);


Теперь все операции уже выполняются параллельно. Дождёмся завершения всей группы:
await Task.WhenAll(
usersTask,
ordersTask,
ratesTask
);


Получим готовые результаты:
string users = await usersTask;
string orders = await ordersTask;
string rates = await ratesTask;


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

Добавим ограничение общего времени ожидания:
using var cts =
new CancellationTokenSource(
TimeSpan.FromSeconds(5)
);


Передадим токен отмены запросу:
string data = await client.GetStringAsync(
usersUrl,
cts.Token
);


Так приложение сможет прекратить операцию, если внешний сервис отвечает слишком долго.

➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥52
Шпаргалка по форматированию даты и времени в C#!

Например, dd.MM.yyyy выведет дату с числом, месяцем и годом, HH:mm покажет время в 24-часовом формате, а MMM и MMMM позволяют получить сокращённое или полное название месяца.

На картинке спецификаторы для дня, месяца, года, часов, минут, секунд, долей секунды, часового пояса и AM/PM. Для каждого варианта приведены готовый формат и пример результата.

Сохрани, чтобы не потерять!

➡️ C# Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥73