Документация по C#
Краткий справочник по C# с примерами. Прочитай концепцию, посмотри код, а затем потренируйся в курсе Coddy.
Начать пошаговый курс по C#Начало работы
- Что такое C#C# это статически типизированный язык общего назначения от Microsoft, который работает на .NET. Для чего он используется, как связан с .NET, что добавила каждая версия и как устроена программа на C#.
- Hello WorldВаша первая программа на C# построчно: метод Main, Console.WriteLine и Write, чтение ввода через Console.ReadLine, комментарии, создание и запуск проекта через dotnet CLI и операторы верхнего уровня.
- C# или JavaC# и Java похожи и решают похожие задачи. Настоящие различия в свойствах, типах значений, обобщениях, LINQ против стримов, async, исключениях и экосистемах вокруг них. Сравнение бок о бок с кодом.
- C# или C++C# это управляемый язык со сборщиком мусора; C++ компилируется в нативный код и даёт ручной контроль над памятью. Как эта разница проявляется в безопасности, производительности, игровых движках, модели сборки и сложности изучения.
- Пространства имён и usingКак пространства имён в C# организуют типы и как директива using их импортирует: псевдонимы, using static, полные имена, исправление неоднозначных ссылок, global using и пространства имён на уровне файла.
Основы
- ПеременныеКак объявлять и присваивать переменные в C#, когда var уместен, а когда нет, как работает область видимости, чем отличаются const, readonly и static readonly, соглашения об именах и ошибка неприсвоенной переменной.
- Типы данныхВсе встроенные типы C# с размером, диапазоном и суффиксом литерала, разница между типами значений и ссылочными типами, почему decimal подходит для денег, переполнение целых чисел и checked, значения по умолчанию.
- Строку в intКак преобразовать строку в int в C# через int.Parse, int.TryParse и Convert.ToInt32, как работают неявные и явные приведения, почему приведение double отбрасывает дробную часть, операторы as и is и почему «1.5» может превратиться в 15.
- ОператорыОператоры C# и их точное поведение: целочисленное деление, остаток от деления с отрицательными числами, инкремент и составное присваивание, сравнение, логика с коротким замыканием, побитовые операторы, операторы null и таблица приоритетов.
- СтрокиКак работают строки в C#: неизменяемость, Length и индексация, сравнение через ==, Equals и string.Compare, escape-последовательности, verbatim-строки с @ и многострочный текст, необработанные строковые литералы, проверки на null и пустоту, перебор символов.
- SubstringКак работает String.Substring в C#: аргументы начального индекса и длины, ArgumentOutOfRangeException и как его избежать, извлечение текста вокруг результатов IndexOf, первые и последние n символов и оператор диапазона из C# 8.
- Интерполяция строкКак работает интерполяция строк $"..." в C#: выражения в фигурных скобках, спецификаторы формата F2, N0, C, D5 и X, выравнивание для таблиц, экранирование скобок, string.Format и составное форматирование, verbatim и необработанные интерполированные строки, форматирование для заданной культуры.
- Методы строкМетоды String, которые используются каждый день в C#: Split с несколькими разделителями и опциями, Replace, Contains и поиск без учёта регистра, IndexOf и LastIndexOf, StartsWith и EndsWith, Trim, ToUpper и ToLower, PadLeft, Join, Concat и переворот строки.
- StringBuilderПочему многократная конкатенация строк в цикле медленная в C# и как это исправляет StringBuilder: Append, AppendLine, AppendFormat, Insert, Remove, Replace, ёмкость и когда лучше обычная конкатенация или string.Join.
- Случайные числаКак генерировать случайные числа в C# с помощью класса Random: Next и его невключённая верхняя граница, случайные double в диапазоне, seed для воспроизводимых результатов, выбор случайного элемента, перемешивание списка, ловушка new Random в цикле и криптографически стойкие числа.
- DateTimeРабота с датами и временем в C#: создание значений DateTime, Now, UtcNow и Today, прибавление дней и месяцев, вычитание с получением TimeSpan, TotalHours и Hours, сравнение дат, DayOfWeek, разбор через ParseExact и TryParse, DateTimeOffset и DateOnly.
- Формат DateTimeКак отформатировать DateTime в строку в C#: стандартные строки формата (d, D, o, s, u, t), пользовательские шаблоны вроде yyyy-MM-dd HH:mm:ss, полная таблица спецификаторов, влияние культуры на вывод, ISO 8601 с "o" и ошибки с mm и MM, hh и HH.
Управление потоком
- if elseКак работают if, else if и else в C#: почему условия должны быть типа bool, объединение проверок через &&, || и !, когда важны фигурные скобки, ранний выход вместо глубокой вложенности, ошибки = вместо == и лишней точки с запятой.
- Оператор switchКак работает оператор switch в C#: switch по значениям int, string, char и enum, почему каждому case нужен break (ошибка CS0163), несколько меток case для нескольких значений, goto case, default, чувствительность к регистру строк и метки case с шаблонами и when.
- Switch-выражениеSwitch-выражение из C# 8 превращает значение в результат с помощью ветвей-шаблонов вместо case и break. Синтаксис, отбрасывание _, шаблоны свойств, кортежей и реляционные, and/or/not, условия when, предупреждения о полноте и SwitchExpressionException, с эквивалентами на C# 7 для запуска.
- Тернарный операторУсловный оператор C# condition ? a : b выбирает одно из двух значений. Как он вычисляется, почему обеим ветвям нужен общий тип (CS0173) и какое приведение это исправляет, вложенные тернарные операторы, скобки в интерполяции строк и когда ?? и ?. выражают мысль лучше.
- Цикл forКак работает цикл for в C#: инициализатор, условие и итератор, обратный отсчёт и шаг, несколько переменных цикла, обход массива по индексу, вложенные циклы, for(;;), ошибки на единицу и удаление элементов во время обхода.
- Цикл foreachКак работает foreach в C#: обход массивов, списков, строк и словарей (KeyValuePair и деконструкция), получение индекса, почему переменная цикла доступна только для чтения, InvalidOperationException «Collection was modified» и как его исправить, что нужно типу для использования в foreach.
- Цикл whileКак работают циклы while и do while в C#: условие проверяется до или после тела, чтение ввода до стоп-слова или до конца ввода, while (true) с break и ошибки с бесконечными циклами, на которых спотыкаются многие.
- break и continueКак работают break, continue и goto в C#: досрочное завершение цикла, пропуск итерации, break внутри switch, три способа выйти из вложенных циклов (флаг, goto или метод с return) и бесконечный цикл из-за continue в while.
Методы и делегаты
- МетодыКак объявлять и вызывать методы в C#: возвращаемые типы и void, параметры, методы с телом-выражением, возврат нескольких значений через кортеж, перегрузка, массивы params, статические и экземплярные методы, метод Main, рекурсия и локальные функции.
- Необязательные параметрыКак работают необязательные параметры и именованные аргументы в C#: значения по умолчанию и правило константы времени компиляции, порядок параметров, пропуск аргументов по имени, необязательные параметры против перегрузок, атрибуты сведений о вызывающем коде и ловушка версий, когда значения по умолчанию вшиты в вызывающий код.
- ref и outКак работают параметры ref, out и in в C#: передача самой переменной вместо копии, out для дополнительных результатов и шаблон TryParse, out var, параметры in только для чтения, правила определённого присваивания и что меняется, когда аргумент ссылочного типа.
- Лямбда-выраженияКак работают лямбда-выражения в C#: синтаксис => во всех формах, хранение лямбд в Func и Action, передача их в методы и LINQ, лямбды с телом-блоком, замыкания на захваченные переменные и ошибка захвата в цикле for, которой нет у foreach.
- ДелегатыЧто такое делегат в C# и как его использовать: объявление типа делегата, создание из метода, лямбды или анонимного метода, вызов, делегаты как обратные вызовы, многоадресные делегаты с += и -=, проверка на null через ?.Invoke и связь делегатов с Func, Action и событиями.
- Func и ActionКак работают Func и Action в C#: Func<T, TResult> для функций, которые возвращают значение, Action<T> для тех, что не возвращают, Predicate и Comparison, передача и возврат функций, словарь команд, асинхронные лямбды и когда объявлять собственный делегат.
- СобытияКак работают события в C#: объявление события через EventHandler и EventHandler<T>, собственные классы EventArgs, подписка и отписка через += и -=, безопасный вызов события через ?.Invoke, почему событие лучше открытого поля-делегата и утечка памяти из-за забытой отписки.
- Методы расширенияКак работают методы расширения в C#: статический метод в статическом классе с this перед первым параметром, вызов как у экземплярного метода, расширение string, перечислений и IEnumerable<T>, как на них построен LINQ, почему побеждают экземплярные методы, вызов на null и нужная директива using.
Коллекции и LINQ
- МассивыМассив в C# это блок фиксированного размера из элементов одного типа. Как объявлять и инициализировать массивы, читать Length, сортировать и искать с помощью класса Array, безопасно копировать массивы и работать с двумерными и зубчатыми массивами.
- ListList<T> это растущий массив в C#. Как создать список, добавлять и вставлять элементы, удалять по значению, индексу или условию, искать через Contains и Find, сортировать по свойству и избежать ошибки при изменении списка внутри foreach.
- DictionaryDictionary<TKey, TValue> сопоставляет ключам значения с быстрым поиском. Как добавлять и обновлять элементы, безопасно читать через TryGetValue, перебирать элементы KeyValuePair, считать вхождения, игнорировать регистр ключей и хранить ключи отсортированными через SortedDictionary.
- HashSetHashSet<T> хранит уникальные элементы и отвечает на Contains за постоянное время. Как Add сообщает о дубликатах, как удалить дубликаты из списка, как объединять, пересекать и вычитать множества и как заставить множество сравнивать ваши объекты по значению.
- QueueQueue<T> это коллекция «первым пришёл, первым вышел»: элементы уходят в том порядке, в каком пришли. Enqueue, Dequeue и Peek, исключение пустой очереди и TryDequeue, поиск в ширину с очередью и когда нужны ConcurrentQueue или PriorityQueue.
- StackStack<T> это коллекция «последним пришёл, первым вышел»: последним добавленный элемент выходит первым. Push, Pop и Peek, исключение пустого стека и TryPop, почему стек перебирается в обратном порядке и два классических применения: история отмены и проверка сбалансированных скобок.
- КортежиКортеж в C# объединяет несколько значений в одно без объявления типа. Синтаксис кортежей-значений, именованные элементы, возврат нескольких значений из метода, деконструкция через var (a, b), кортежи как ключи словаря и чем ValueTuple отличается от старого System.Tuple.
- LINQLINQ добавляет операторы запросов к каждой коллекции в C#. Синтаксис методов и синтаксис запросов, фильтрация через Where, проекция через Select, сортировка через OrderBy и ThenBy, группировка через GroupBy, ловушка First и FirstOrDefault, агрегаты и как отложенное выполнение меняет момент запуска запроса.
- IEnumerable и yieldIEnumerable<T> это интерфейс, на котором работают foreach и LINQ, а yield return это самый простой способ его реализовать. Как IEnumerable связан с ICollection и List, как пошагово выполняется метод-итератор, yield break, бесконечные последовательности и ловушки ленивого вычисления.
Классы и типы
- Классы и объектыКак объявить класс в C#, добавить ему поля и методы, создавать объекты через new и что значит, что класс это ссылочный тип: общие объекты, null и NullReferenceException, ToString и инициализаторы объектов.
- КонструкторыКак работают конструкторы в C#: неявный конструктор по умолчанию и когда он исчезает, конструкторы с параметрами и их перегрузка, цепочки через this(...) и base(...), порядок выполнения, статические и закрытые конструкторы и первичные конструкторы C# 12.
- СвойстваКак работают свойства в C#: методы доступа get и set поверх поля хранения, автосвойства, private set и свойства только для чтения, вычисляемые свойства, проверка в сеттерах и ключевые слова init и required из C# 9 и 11.
- Ключевое слово staticЧто означает static в C#: члены, принадлежащие типу, а не объекту, общее состояние всех экземпляров, статические методы и классы, статические конструкторы, const и static readonly, using static и ошибка CS0120.
- Модификаторы доступаШесть модификаторов доступа C# (public, private, protected, internal, protected internal, private protected), что разрешает каждый, значения по умолчанию, когда модификатор не указан, и ошибки компилятора, которые они вызывают.
- НаследованиеКак работает наследование классов в C#: наследование через двоеточие, что наследуется и что нет, вызов базового класса через base, virtual и override, сокрытие через new (и вывод, который удивляет всех), sealed, полиморфизм и приведение вверх и вниз по иерархии.
- Абстрактные классыЧто такое абстрактный класс в C#: базовый класс, экземпляр которого нельзя создать и который может объявлять абстрактные члены, обязательные для реализации в производных классах. Абстрактные методы и свойства, конструкторы, шаблонный метод и когда вместо него выбрать интерфейс.
- ИнтерфейсыКак работают интерфейсы в C#: объявление, реализация в классах и структурах, интерфейс как тип, реализация нескольких интерфейсов сразу, явная реализация, интерфейсы фреймворка, которые вы будете реализовывать чаще всего (IComparable<T>, IEnumerable<T>, IDisposable), и методы интерфейса по умолчанию из C# 8.
- СтруктурыКак работают структуры в C#: семантика значений и копирование при присваивании, ошибка изменения элемента List<T>, правила конструкторов, равенство, упаковка, readonly struct и record struct, а также сравнение struct и class с рекомендациями, когда структура это правильный выбор.
- Перечисления enumКак работают перечисления в C#: объявление именованных констант, целочисленные значения и приведение, преобразование enum в строку и строки в enum через Parse и TryParse, перечисление всех значений, [Flags] с побитовыми операторами и HasFlag, switch по enum и обработка неопределённых значений.
- Записи recordЧто такое записи в C# (C# 9 и новее): позиционный синтаксис, члены, которые генерирует компилятор, равенство по значению, неразрушающие копии через with, встроенный ToString, record struct из C# 10, наследование между записями и эквивалентный класс, написанный вручную.
- ОбобщенияКак работают обобщения в C#: обобщённые классы и методы с параметрами типа, вывод типов, ограничения через where (class, struct, new(), базовые классы, интерфейсы), default(T), статические члены для каждого типа и ковариантность через IEnumerable<out T>.
- Типы, допускающие nullВсё о null в C#: типы значений, допускающие null (int?, Nullable<T>), с HasValue, Value и GetValueOrDefault, операторы объединения с null ?? и ??=, null-условный оператор ?., проверки на null и ссылочные типы, допускающие null (string?), из C# 8.
- Сопоставление с образцомКак работает сопоставление с образцом (pattern matching) в C#: оператор is с шаблонами типа и констант, операторы switch с шаблонами в case и when, switch-выражения, шаблоны свойств, кортежей и позиционные, реляционные и логические шаблоны (and, or, not), шаблоны списков и в какой версии C# появился каждый из них.
Исключения
- Try Catchtry, catch и finally это способ обработки исключений в C#. Как исключение поднимается по стеку вызовов, как перехватывать конкретные типы исключений в правильном порядке, фильтровать через when, освобождать ресурсы в finally, повторно выбрасывать через throw; без потери трассировки стека и какие исключения не стоит перехватывать.
- Выброс исключенийКак и когда выбрасывать исключения в C#. Оператор throw, какой встроенный тип исключения подходит к какой ошибке, выражения throw с ?? и ?:, вспомогательные методы ThrowIfNull и как написать собственный класс исключения со своими данными и внутренним исключением.
- Оператор usingОператор using гарантирует вызов Dispose для файлов, потоков, подключений и других объектов IDisposable, даже когда выброшено исключение. Во что он компилируется, в каком порядке освобождаются объекты, объявление using из C# 8 и как реализовать IDisposable в собственном классе.
Асинхронность и потоки
- Async Awaitasync и await позволяют коду на C# ждать медленные операции, не блокируя поток. Как выполняется асинхронный метод, Task и Task<T>, одновременный запуск независимых операций через Task.WhenAll, исключения в асинхронном коде и почему async void и .Result приводят к ошибкам и взаимоблокировкам.
- Задачи TaskTask это единица асинхронной и параллельной работы в .NET. Task.Run для работы, нагружающей процессор, чтение результатов, объединение задач через WhenAll и WhenAny, продолжения, отмена через CancellationToken, чем Task отличается от Thread и когда лучше подходит Parallel.For.
- LockОператор lock позволяет выполнять блок кода только одному потоку одновременно. Посмотрите, как состояние гонки портит счётчик, исправьте это через lock, узнайте, на каком объекте блокироваться, используйте Interlocked для простых счётчиков, избегайте взаимоблокировок из-за порядка блокировок и берите SemaphoreSlim, когда код внутри использует await.
- ТаймерыВ C# несколько классов таймеров, и ведут они себя по-разному. Когда использовать System.Threading.Timer, System.Timers.Timer, PeriodicTimer или таймер интерфейса, как их запускать и останавливать, почему обратные вызовы выполняются в пуле потоков и могут перекрываться, почему на таймер должна оставаться ссылка и как измерять прошедшее время через Stopwatch.
Файлы, JSON и не только
- Чтение и запись файловКак записать данные в файл и прочитать файл в C#: File.WriteAllText, ReadAllText, AppendAllText, WriteAllLines и ReadAllLines для целых файлов, StreamWriter и StreamReader для больших, пути через Path.Combine, каталоги, кодировки и исключения, которые должен обрабатывать код работы с файлами.
- JSONКак работать с JSON в C# через System.Text.Json: JsonSerializer.Serialize и Deserialize, camelCase и форматированный вывод, атрибуты JsonPropertyName и JsonIgnore, перечисления в виде строк, чтение JSON без классов через JsonDocument и JsonNode, ошибки и сравнение с Newtonsoft.Json.
- RegexКак использовать регулярные выражения в C# через System.Text.RegularExpressions: IsMatch, Match и Matches, нумерованные и именованные группы, Replace с подстановками и лямбдой, Split, RegexOptions, verbatim-строки для шаблонов, проверка ввода, тайм-ауты и атрибут GeneratedRegex из .NET 7.
- Рефлексия и атрибутыКак работает рефлексия в C#: объекты Type из typeof и GetType, чтение и запись свойств, вызов методов по имени, создание экземпляров, а также атрибуты: встроенные вроде Obsolete, объявление собственных и их чтение во время выполнения. Плюс цена рефлексии.