C# (C Sharp) programming
18.7K subscribers
759 photos
39 videos
8 files
677 links
По всем вопросам- @haarrp

C# - обучающий канал Senior C# разработчика.

@ai_machinelearning_big_data - Machine learning

@itchannels_telegram - 🔥лучшие ит-каналы

@csharp_ci - C# академия

@pythonlbooks- книги📚

Реестр РКН: https://clck.ru/3Fk3kb
Download Telegram
Вам когда-нибудь требовалось реализовать полнофункциональный текстовый редактор в вашем приложении C#?

Просто прочтите эту интересную статью по ссылке, где автор представляет текстовый редактор, основанный на классе RichtextBox.
Исходники находятся на сервере Codeproject, мне понадобилось аж три попытки, чтобы их скачать 😲

Надеюсь, скоро автор перенесет этот полезный проект на GitHub, а пока вот ссылка

🔗Статья и проект

@csharp_ci
🖥 Полезные фишки, связанные с символом @

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

▶️указать, что строковый литерал следует интерпретировать буквально. Символ @ в этом случае определяет буквальный строковый литерал. Простые escape-последовательности (например, "\\" для обратной косой черты), шестнадцатеричные escape-последовательности (например, "\x0041" для прописной буквы A) и escape-последовательности Юникода (например, "\u0041" для прописной буквы A) интерпретируются буквально. Только escape-последовательность кавычки ("") не интерпретируется буквально. Кроме того, в случае с интерполированными последовательностями строковых фигурных фигурных скобок ({{ и }}) не интерпретируются буквально; они создают символы с одной фигурной скобкой.
string filename1 = @"c:\documents\files\u0066.txt";
string filename2 = "c:\\documents\\files\\u0066.txt";

Console.WriteLine(filename1);
Console.WriteLine(filename2);

// c:\documents\files\u0066.txt
// c:\documents\files\u0066.txt


string s1 = "He said, \"This is the last \u0063hance\x0021\"";
string s2 = @"He said, ""This is the last \u0063hance\x0021""";

Console.WriteLine(s1);
Console.WriteLine(s2);

// He said, "This is the last chance!"
// He said, "This is the last \u0063hance\x0021"


▶️@ можно использовать в качестве идентификаторов. Символ @ предшествует элементу кода, который компилятор должен интерпретировать как идентификатор, а не ключевое слово C#:
string[] @for = { "John", "James", "Joan", "Jamie" };
for (int ctr = 0; ctr < @for.Length; ctr++)
{
Console.WriteLine($"Here is your gift, {@for[ctr]}!");
}

// Here is your gift, John!
// Here is your gift, James!
// Here is your gift, Joan!
// Here is your gift, Jamie!


▶️ну и напоследок, @ используется, чтобы позволить компилятору различать атрибуты в случае конфликта имен.

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
💎Свежайший 8-часовой ролик-курс по C# от freeCodeCamp.org

Здесь разбираются самые важные понятия, очень много практики — на протяжении ролика постоянно реализуются мини-проекты

А вот темы, которые затрагиваются в ролике:
Обзор языка С#
🔘Структура программы на С#
🔘Основные операции ввода/вывода
🔘Рекомендации по оформлению кода

Использование структурных переменных
🔘Общая система типов (Common Type System)
🔘Использование встроенных типов данных
🔘Пользовательские типы данных
🔘Преобразование типов

Операторы и исключения
🔘Операторы в С#
🔘Обработка исключений

Методы и параметры
🔘Использование методов
🔘Использование параметров
🔘Перегрузка методов

Массивы и коллекции
🔘Массивы
🔘Списки – List<T>
🔘Двухсвязные списки – LinkedList<T>
🔘Словари – Dictionary<TKey, TValue>

Основы ООП
🔘Классы и объекты
🔘Инкапсуляция данных
🔘Наследование и полиморфизм

Использование ссылочных данных
🔘Reflection (рефлексия)
🔘Пространства имен
🔘Приведение типов данных

Создание и удаление объектов
🔘Использование конструкторов
🔘Уничтожение объектов

Наследование в C#
🔘Использование интерфейсов
🔘Использование абстрактных классов

Агрегации, пространства имён, сборки и модули
🔘Использование внутренних (internal) классов, методов и данных
🔘Использование агрегаций
🔘Фабрики классов
🔘Пространства имен
🔘Модули и сборки

Операции, делегаты, события
🔘Операции
🔘Создание и использование делегатов
🔘События

Свойства и индексаторы
🔘Свойства
🔘Индексаторы

Посмотрите хотя бы по диагонали — прокачаете свой C#

💎 Learn C# – Full Course with Mini-Projects

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥Подборка лучших обучающих каналов для программистов.

➡️ Делитесь с коллегами и cохраняйте себе, чтобы не потерять

⚡️ Frontend
Javascript академия - крупнейший js канал
React - лучшие гайды и советы по работе с react
Frontend - тутрориалы, уроки, гайды, код
PHP
Книги frontend
Задачи frontend

💥 Хакинг Kali Linux

Kali linux
linux_kal - kali чат
Информационная безопасность

🚀 Data Science

Анализ данных - полезные фишки, код, гайды и советы, маст-хэв датасаентиста
Data Jobs - ds вакансии
Аналитик данных
Data Science книги - актуальные бесплатные книги
Big data

#️⃣C#

С# академия
С# заметки — код, лучшие практики, заметки программиста c#
С# задачи и тесты
С# библиотека - актуальные бесплатные книги
C# вакансии - работа

Машинное обучение

Ml Собеседование - подготовка к собеседовению мл, алгоритмам, кодингу
Ml ru - актуальные статьи, новости, код и обучающие материалы
Ml Jobs - вакансии ML
ML Книги - актуальные бесплатные книги МО
ML чат
Machine Learning - полезные статьи новости гайды и разбор кода

🏆 Golang
Golang - подробные гайды, разбор кода, лучшие практики, заметки
Golang собеседование
Golang вакансии
Golang книги
Golang задачи и тесты
Golang чат
Golang news - новости go

🐍 Python

Python/django
Python Собеседование - подготовка к собеседовению python и разбор алгоритмов
Pro python - статьи, новости, код и обучающие материалы
Python Jobs - вакансии Python
Python чат
Python книги

Java

Java академия
Java вакансии
Java чат
Java вопросы с собеседований
Java книги

🛢Базы данных
Sql базы данных
Библиотека баз данных
SQL чат

💻 C++

C++ академия
С++ книги
C++ задачи - подготовка к собеседовению мл, алгоритмам
C++ вакансии

🐧 Linux

Linux academy

🦀 Rust
Rust программирование
Rust чат
Rust книги для программистов

📲 Мобильная разработка
Android разработка
Мобильный разработчик гайды и уроки

🇬🇧 Английский для программистов

🧠 Искусственный интеллект
ИИ и технологии
Neural - нейросети для работы и жизни
Книги ИИ
Artificial Intelligence

🔥 DevOPs
Devops для программистов
Книги Devops

🌟 Docker/Kubernets
Docker
Kubernets

📓 Книги
Библиотеки Книг для программситов

💼 Папка с вакансиями:
Папка Go разработчика:
Папка Python разработчика:
Папка Data Science
Папка Java разработчика
Папка C#
Папка Frontend
🖥 Немного о новых фичах C# 12

▶️В C# 12 упрощен способ создания массивов и коллекций с помощью выражения коллекций (collection expression), которые представляют унифицированный подход к созданию коллекций. Так, если раньше создание массивов выглядело так:
int[] nums1 = { 1, 2, 3, 4 };
int[] nums2 = new int[] { }; // пустой массив

Теперь можно писать так:
int[] nums1 = [ 1, 2, 3, 4 ];
int[] nums2 = []; // пустой массив


Аналогичным образом можно использовать выражения коллекций для создания других типов коллекций:
List<int> list1 = [1, 2, 3, 4];
List<int> list2 = []; // пустой список
Span<int> span1 = [1, 2, 3, 4];



▶️Первичные конструкторы (Primary constructors) позволяют добавлять параметры к определению класса/структуры и использовать эти параметры внутри класса/структуры:
var tom = new Person("Tom", 38);
Console.WriteLine(tom);

public class Person(string name, int age)
{
public Person(string name) : this(name, 18) { }
public string Name => name;
public int Age => age;

public override string ToString() => $"name: {name}, age: {age}";
}

Здесь для класса Person определен первичный конструктор с двумя параметрами - name и age. Эти параметры применяются для инициализации свойств Name и Age и используются в методе ToString().

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

Кроме первичных конструкторов класс может определять дополнительные конструкторы, как примере выше. Но эти дополнительные конструкторы должны вызывать первичный конструктор:
public Person(string name) : this(name, 18) { }



Разумеется, это не все фичи C# 12, вот подробнее:
📎 Youtube
📎 Статья в тему

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 О использовании структур размером больше 16 байт

По умолчанию, при передаче в метод/возврате из метода, экземпляры значимых типов копируются, тогда как экземпляры ссылочных типов передаются по ссылке.
В 2008 была выпущена книга «Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries». В ней рекомендовалось не использовать структуры больше 16 байт, поскольку, очевидно, структуры большего размера копируются медленнее. Прошло уже 16 лет, но в сообществе C# разработчиков до сих пор популярно мнение, что производительность структур размером больше 16 байт хуже. Даже Google на запрос «recommended structure size c#» говорит, что это не более 16 байт.

Код бенчмарка очень прост. Он содержит структуры и классы размером от 4 до 160 байт, с шагом 4 байта.

Для каждой структуры и класса есть соответствующий метод, который из параметра типа int cоздаёт соответствующий экземпляр и возвращает его.

И, самое главное, есть непосредственно бенчмарк методы (картинка), каждый из которых создаёт список структур или классов. Размер списка – 1000 элементов.

В общем, после проведения тестов можно убедиться, что использование структур размером больше 16 байт не ухудшает производительность. Сейчас этой границей является размер 64 байта.

А ты знал про это?

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Найди ошибку в этом коде C# и реши задание правильно

Чисто академическое задание но почему бы и нет 🙃
Вот неправильное решение, подумай, какие в нём ошибки и напиши по красоте.

Готово? Получилось? Можешь смотреть решение

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Итак, реальный кейс: нужно записать значение каждой строки InputField в List<string>

Эти 2 варианта ниже неправильные, они не работают:
List = (InputField.text).ToList
List = InputField.text

Так как InputField.text это тип string , я не могу преобразовать его в List<string>. Что в итоге делать?


Всё довольно просто, можно записать строки InputField в List<string> вот так:
string text = InputField.text;
string[] lines = text.Split(Environment.NewLine);


Или, если C# так не поддерживает в Unity первый вариант, то тогда вот так:
string[] lines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);


Вообще, если хочется получить список из массива, то:
List<string> list = lines.ToList();

Но если нет необходимости список модифицировать, лучше оставить массив.

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Создание бесконечно повторяющегося метода в C#

Итак задача:
как создать бесконечно повторяющийся метод в C#, который работает на протяжении работы приложения?
Предположим, метод должен через определенное количество времени выводить какую-то информацию на экран; он должен работать вне зависимости от действий пользователя.


Если в двух словах, то для этого можно использовать асинхронность.
Итак, создаём:
private async Task RunLoopAsync(CancellationToken token)
{
try
{
while (true)
{
// ... что-то сделать
await Task.Delay(1000, token); // подождать одну секунду
}
}
catch (OperationCanceledException)
{ } // сработала отмена, ничего не делать
}

и вот так это можно использовать:
private CancellationTokenSource _cts;

private async void StartLoop()
{
if (_cts != null)
return;
try
{
using (_cts = new CancellationTokenSource())
{
await RunLoopAsync(_cts.Token);
}
}
catch (Exception ex)
{
// ... ex.Message
}
_cts = null;
}

private void StopLoop()
{
_cts?.Cancel();
}


📎 Читать подробнее

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет на экран это код?
Anonymous Quiz
23%
100 100
11%
1000 1000
65%
100 1000
🖥 Как распарсить HTML в .NET?

🔜 Итак, реальный кейс:
Необходимо извлечь все URL из атрибутов href тегов a в HTML странице. Можно попробовать воспользоваться регулярными выражениями:
Uri uri = new Uri("https://google.com/search?q=test");
Regex reHref = new Regex(@"<a[^>]+href=""([^""]+)""[^>]+>");
string html = new WebClient().DownloadString(uri);
foreach (Match match in reHref.Matches(html))
Console.WriteLine(match.Groups[1].ToString());


Но возникает множество потенциальных проблем:
— Как отфильтровать только специфические ссылки, например, по CSS классу?
— Что будет, если кавычки у атрибута другие?
— Что будет, если вокруг знака равенства пробелы?
— Что будет, если кусок страницы закомментирован?
— Что будет, если попадётся кусок JavaScript?
— И так далее.
Регулярное выражение очень быстро становится нечитаемым. Какие есть другие варианты?


🔜 Для парсинга HTML используйте AngleSharp

Проверенный игрок на поле парсеров. В отличие от CsQuery, написан с нуля вручную на C#. Также включает парсеры других языков.

API построен на базе официальной спецификации по JavaScript HTML DOM. Изначально содержал в некоторых местах странности, непривычные для разработчиков на .NET (например, при обращении к неверному индексу в коллекции будет возвращён null, а не выброшено исключение), но разработчик в конце концов сдался и исправил самые жуткие костыли. Что-то ушло само, например, Microsoft BCL Portability Pack. Что-то осталось, например, пространства имён очень гранулярные, даже базовое использование библиотеки требует три using и т. п.), но в целом ничего критичного.

Обработка HTML простая, к примеру вот:
IHtmlDocument angle = new HtmlParser().ParseDocument(html);
foreach (IElement element in angle.QuerySelectorAll("a"))
Console.WriteLine(element.GetAttribute("href"));


📎 Читать подробнее

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Humanizer C#

Humanizer — бесплатная .NET-библиотека с открытым исходным кодом, которая предлагает набор методов для манипулирования строками, числами, датами, временем, временными интервалами, цифрами и величинами в удобном для человеческого восприятия виде.

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


🔵Форматирование DateTime в удобочитаемый вид
Один из самых простых способов гуманизировать объект DateTime — использовать метод расширения Humanize, который возвращает время и дату на естественном языке. Например:

using Humanizer;

DateTime now = DateTime.Now;
DateTime yesterday = now.AddDays(-1);
DateTime tomorrow = now.AddDays(1);
DateTime nextWeek = now.AddDays(7);

Console.WriteLine(now.Humanize()); // сейчас
Console.WriteLine(yesterday.Humanize()); // вчера
Console.WriteLine(tomorrow.Humanize()); // через 23 часа
Console.WriteLine(nextWeek.Humanize()); // через 6 дней

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


🔵Еще один способ гуманизации объекта DateTime — использовать метод расширения Humanize с булевым параметром, указывающим, отображать относительное время или нет. Относительное время — это строка, которая представляет, сколько времени прошло с или пройдет до конкретного момента. Например:

using Humanizer;

DateTime anHourAgo = DateTime.Now.AddHours(-1);
DateTime anHourLater = DateTime.Now.AddHours(1);

Console.WriteLine(anHourAgo.Humanize()); // час назад
Console.WriteLine(anHourLater.Humanize()); // через 59 минут


🔵Как-то вот так можно использовать Humanizer для управления датой и временем.
📎 Подробнее можно почитать тут

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Задачка с собеседования от Сбера:

Вставьте код функции Mutate (без использования ключевого слова unsafe), чтобы на консоль вывелось «404». Сигнатуру функции не менять, замыкания не ловить


const string constStr = "000";

Mutate(constStr);

var nonConst = "000";

Console.WriteLine(nonConst);



void Mutate(string str)

{

// write your code here

}


Вот пример решения, которое полностью устроило лида, который собеседовал кандидата.


void Mutate(string str)
{
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);

IntPtr pointer = handle.AddrOfPinnedObject();

Marshal.WriteByte(pointer, 0, (byte)'4');
Marshal.WriteByte(pointer, 4, (byte)'4');

handle.Free();
}


Весь смысл кроется в том, как работают строки в .net (интернирование), что такое pinned object и как работать с unmanaged кодом.

Идея интернирования строк состоит в том, чтобы хранить в памяти только один экземпляр типа String для идентичных строк. При старте нашего приложения виртуальная машина создаёт внутреннюю хэш-таблицу, которая называется таблицей интернирования (иногда можно встретить название String Pool).

Pinned Object Heap (POH, Куча Закрепленных Объектов). В отличие от других видов кучи, эта доступна разработчикам явно (что не характерно для сборщика мусора).

Пишите свое решение в комментариях👇


@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Ловите полезные ссылки для изучения асинхронности в C#

Асинхронность вызывает большие проблемы у многих, но выход есть — вот:

*️⃣ Во-первых, стоит прочитать весь блок статей на MSDN

*️⃣ Первый гигант async/await — Stephen Cleary. Вводная статья

*️⃣ Статья об устройстве async/await под капотом. Не обязательно заучивать всю машину состояний под await, но тут как с блоком итератора yield - код пишется, а руки трясутся.

*️⃣ На этом этапе может начаться каша в голове и встреча с SynchronizationContext. Начать можно с этой статьи на MSDN. Но если она покажется душной, переходите к пункту 5.

*️⃣ Второй гигант, и тоже Stephen. Я советую перечитать все статьи обоих, что можно найти. Но продолжая тему контекста синхронизации — эта статья крайне важна для тех, кто тренируется в консольных приложениях. Вопрос об асинхронности/многопоточности уходит после нее. И небольшой, но классный ответ на StackOverflow о TaskScheduler.

*️⃣ Но если вопрос все же не ушел — There is no thread. Также советую загуглить словосочетание из этой статьи — naturally-asynchronous operations.

*️⃣ Для закрепления пунктов 4,5,6 можно почитать о Task.Run (и комплексных случаях использования многопоточности и асинхронности). Внутри этого блока статей много полезных ссылок и на другие материалы.

*️⃣ Лучшие практики от Cleary. Кстати, у него есть книга по асинхронности, можно ознакомиться при желании.

*️⃣ Обработка исключений.

@csharp_ci
Please open Telegram to view this post
VIEW IN TELEGRAM