C# 14 и .NET 10: от поверхностного знания к рабочему (Extended)
Курс для программистов, которые C# «в целом знают», но на код-ревью и на собеседовании проваливаются на вопросах «почему так, а не иначе». Язык разбирается не как список конструкций, а как набор решений с ценой: значимые и ссылочные типы, память и сборщик мусора, равенство, null, сопоставление с образцом, строки и Span, обобщения, коллекции, LINQ, исключения, async и конкурентность, данные на границе процесса, рефлексия и генераторы кода. Затем пять юнитов на SOLID — каждый принцип как ответ на конкретную боль, а не как лозунг. Затем паттерны проектирования — порождающие, структурные, поведенческие и прикладные паттерны .NET — с обязательным разбором, когда паттерн вредит. Финал — тестируемость, разговор об архитектуре вслух и обзор нового в C# 13 и 14. Необязательная ветка «C# в приложении» доводит язык до работающего сервиса: хост и DI, Minimal API, HttpClient и фоновые задачи, EF Core, тесты, выпуск в Azure. Все примеры — в одной системе, бэкенде ENGAGE вымышленной компании Aldervane. C# 14 / .NET 10 LTS.
Votre leçon est dans votre langue : c’est votre assistant qui la mène.
- Contenu: russe
- Examen: russe — passé sur le site, non traduit
Comment ça marche
Votre assistant récupère le contenu du cours sur notre serveur et mène la leçon dans votre langue.
L’examen se passe sur le site, sans assistant. Les questions d’examen ne sont pas traduites : c’est la règle pour tous les cours.
Parcours du cours
· 38 unitésl’ordre est libre · les étapes ci-dessous sont l’ordre suggéré par l’auteur, pas une conditionAffichage: carte · niveaux
Niveau 1
~2 h
Niveau 2
~2 h
2 · selon le plan de l’auteur, après « Что на самом деле происходит, когда вы жмёте F5 »
Значимые и ссылочные типы: стек, куча и упаковка
~2 h
Niveau 3
~5,5 h
selon le plan de l’auteur, après « Значимые и ссылочные типы: стек, куча и упаковка »
Niveau 4
~7,5 h
5 · selon le plan de l’auteur, après « class, struct, record: чем объявлять данные »
Равенство, хеш и сравнение: контракт, который легко нарушить
~2 h
6 · selon le plan de l’auteur, après « class, struct, record: чем объявлять данные »
null: nullable-типы, ссылочная нулевая аннотация и что с этим делать
~1,5 h
28 · selon le plan de l’auteur, après l’une de celles-ci : « Значимые и ссылочные типы: стек, куча и упаковка », « Строки: неизменяемость, интернирование, StringBuilder, Span »
Span, Memory, ref struct и как мерить
~2 h
8 · selon le plan de l’auteur, après « class, struct, record: чем объявлять данные »
Инкапсуляция и конструирование: объект, который нельзя собрать неправильно
~2 h
Niveau 5
~8 h
27 · selon le plan de l’auteur, après l’une de celles-ci : « class, struct, record: чем объявлять данные », « null: nullable-типы, ссылочная нулевая аннотация и что с этим делать »
Сопоставление с образцом, кортежи, деконструкция
~2 h
9 · selon le plan de l’auteur, après « Инкапсуляция и конструирование: объект, который нельзя собрать неправильно »
Наследование и полиморфизм: virtual, override, new, sealed
~2 h
11 · selon le plan de l’auteur, après « Инкапсуляция и конструирование: объект, который нельзя собрать неправильно »
Делегаты, лямбды, замыкания, события
~2 h
15 · selon le plan de l’auteur, après « Инкапсуляция и конструирование: объект, который нельзя собрать неправильно »
Исключения: чем они являются и чем не являются
~2 h
Niveau 6
~4 h
10 · selon le plan de l’auteur, après « Наследование и полиморфизм: virtual, override, new, sealed »
Интерфейсы: контракт, явная реализация, DIM
~1,5 h
16 · selon le plan de l’auteur, après « Делегаты, лямбды, замыкания, события »
async/await: что это и чего это не
~2,5 h
Niveau 7
~8 h
12 · selon le plan de l’auteur, après « Интерфейсы: контракт, явная реализация, DIM »
Обобщения: ограничения, реификация, вариантность
~2 h
30 · selon le plan de l’auteur, après l’une de celles-ci : « Исключения: чем они являются и чем не являются », « async/await: что это и чего это не »
Данные на границе: JSON, файлы и потоки, даты и время
~2 h
29 · selon le plan de l’auteur, après « async/await: что это и чего это не »
Конкурентность: lock, Lock, Interlocked, SemaphoreSlim, Channel, Parallel
~2 h
17 · selon le plan de l’auteur, après « Интерфейсы: контракт, явная реализация, DIM »
SRP: одна причина для изменения
~2 h
Niveau 8
~6 h
31 · selon le plan de l’auteur, après l’une de celles-ci : « Что на самом деле происходит, когда вы жмёте F5 », « Обобщения: ограничения, реификация, вариантность »
Метаданные: рефлексия, атрибуты, генераторы кода
~2 h
13 · selon le plan de l’auteur, après « Обобщения: ограничения, реификация, вариантность »
Коллекции: выбор структуры данных и её цена
~2 h
18 · selon le plan de l’auteur, après « SRP: одна причина для изменения »
OCP: открыт для расширения, закрыт для изменения
~2 h
Niveau 9
~4 h
14 · selon le plan de l’auteur, après « Коллекции: выбор структуры данных и её цена »
LINQ: отложенное выполнение, yield, IQueryable
~2 h
19 · selon le plan de l’auteur, après « OCP: открыт для расширения, закрыт для изменения »
LSP: подтип обязан быть заменяемым
~2 h
Niveau 10
~1,5 h
20 · selon le plan de l’auteur, après « LSP: подтип обязан быть заменяемым »
ISP: клиента не заставляют зависеть от лишнего
~1,5 h
Niveau 11
~2,5 h
21 · selon le plan de l’auteur, après « ISP: клиента не заставляют зависеть от лишнего »
~2,5 h
Niveau 12
~8 h
22 · selon le plan de l’auteur, après « DIP и внедрение зависимостей »
Порождающие паттерны: кто и как создаёт объекты
~2 h
23 · selon le plan de l’auteur, après « DIP и внедрение зависимостей »
Структурные паттерны: как собирать объекты в целое
~2 h
24 · selon le plan de l’auteur, après « DIP и внедрение зависимостей », « Делегаты, лямбды, замыкания, события »
Поведенческие паттерны: кто кого вызывает и когда
~2 h
33 · C# в приложении · selon le plan de l’auteur, après « DIP и внедрение зависимостей »
Хост, DI на практике, конфигурация, логирование
~2 h
Niveau 13
~8 h
25 · selon le plan de l’auteur, après 2 de celles-ci : « Порождающие паттерны: кто и как создаёт объекты », « Структурные паттерны: как собирать объекты в целое », « Поведенческие паттерны: кто кого вызывает и когда »
Прикладные паттерны .NET: Repository, Options, CQRS, Result
~2 h
34 · C# в приложении · selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование »
Minimal API: конвейер, привязка, валидация, ошибки
~2 h
35 · C# в приложении · selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование », « async/await: что это и чего это не »
HttpClient, устойчивость и фоновые задачи
~2 h
36 · C# в приложении · selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование », « LINQ: отложенное выполнение, yield, IQueryable »
~2 h
Niveau 14
~4,5 h
26 · selon le plan de l’auteur, après « Прикладные паттерны .NET: Repository, Options, CQRS, Result », « async/await: что это и чего это не »
Финал: тестируемость и разговор об архитектуре вслух
~2,5 h
38 · C# в приложении · selon le plan de l’auteur, après « Minimal API: конвейер, привязка, валидация, ошибки »
Выпуск в Azure: App Service, секреты, managed identity
~2 h
Niveau 15
~4 h
32 · selon le plan de l’auteur, après « Финал: тестируемость и разговор об архитектуре вслух »
Что нового в C# 13 и 14 и как об этом спрашивают
~2 h
37 · C# в приложении · selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование », « Финал: тестируемость и разговор об архитектуре вслух »
Тесты сервиса: от модуля до HTTP
~2 h
Examen
fermée · inscrivez-vous au cours
final · dans le navigateur, sans l’assistant
Examen
Le parcours en mots
- Niveau 1 · Что на самом деле происходит, когда вы жмёте F5 — ~2 h
- Niveau 2 · Значимые и ссылочные типы: стек, куча и упаковка — selon le plan de l’auteur, après « Что на самом деле происходит, когда вы жмёте F5 »; ~2 h
- Niveau 3 · Память и время жизни: сборщик мусора, IDisposable, using — selon le plan de l’auteur, après « Значимые и ссылочные типы: стек, куча и упаковка »; ~2 h
- Niveau 3 · class, struct, record: чем объявлять данные — selon le plan de l’auteur, après « Значимые и ссылочные типы: стек, куча и упаковка »; ~2 h
- Niveau 3 · Строки: неизменяемость, интернирование, StringBuilder, Span — selon le plan de l’auteur, après « Значимые и ссылочные типы: стек, куча и упаковка »; ~1,5 h
- Niveau 4 · Равенство, хеш и сравнение: контракт, который легко нарушить — selon le plan de l’auteur, après « class, struct, record: чем объявлять данные »; ~2 h
- Niveau 4 · null: nullable-типы, ссылочная нулевая аннотация и что с этим делать — selon le plan de l’auteur, après « class, struct, record: чем объявлять данные »; ~1,5 h
- Niveau 4 · Span, Memory, ref struct и как мерить — selon le plan de l’auteur, après l’une de celles-ci : « Значимые и ссылочные типы: стек, куча и упаковка », « Строки: неизменяемость, интернирование, StringBuilder, Span »; ~2 h
- Niveau 4 · Инкапсуляция и конструирование: объект, который нельзя собрать неправильно — selon le plan de l’auteur, après « class, struct, record: чем объявлять данные »; ~2 h
- Niveau 5 · Сопоставление с образцом, кортежи, деконструкция — selon le plan de l’auteur, après l’une de celles-ci : « class, struct, record: чем объявлять данные », « null: nullable-типы, ссылочная нулевая аннотация и что с этим делать »; ~2 h
- Niveau 5 · Наследование и полиморфизм: virtual, override, new, sealed — selon le plan de l’auteur, après « Инкапсуляция и конструирование: объект, который нельзя собрать неправильно »; ~2 h
- Niveau 5 · Делегаты, лямбды, замыкания, события — selon le plan de l’auteur, après « Инкапсуляция и конструирование: объект, который нельзя собрать неправильно »; ~2 h
- Niveau 5 · Исключения: чем они являются и чем не являются — selon le plan de l’auteur, après « Инкапсуляция и конструирование: объект, который нельзя собрать неправильно »; ~2 h
- Niveau 6 · Интерфейсы: контракт, явная реализация, DIM — selon le plan de l’auteur, après « Наследование и полиморфизм: virtual, override, new, sealed »; ~1,5 h
- Niveau 6 · async/await: что это и чего это не — selon le plan de l’auteur, après « Делегаты, лямбды, замыкания, события »; ~2,5 h
- Niveau 7 · Обобщения: ограничения, реификация, вариантность — selon le plan de l’auteur, après « Интерфейсы: контракт, явная реализация, DIM »; ~2 h
- Niveau 7 · Данные на границе: JSON, файлы и потоки, даты и время — selon le plan de l’auteur, après l’une de celles-ci : « Исключения: чем они являются и чем не являются », « async/await: что это и чего это не »; ~2 h
- Niveau 7 · Конкурентность: lock, Lock, Interlocked, SemaphoreSlim, Channel, Parallel — selon le plan de l’auteur, après « async/await: что это и чего это не »; ~2 h
- Niveau 7 · SRP: одна причина для изменения — selon le plan de l’auteur, après « Интерфейсы: контракт, явная реализация, DIM »; ~2 h
- Niveau 8 · Метаданные: рефлексия, атрибуты, генераторы кода — selon le plan de l’auteur, après l’une de celles-ci : « Что на самом деле происходит, когда вы жмёте F5 », « Обобщения: ограничения, реификация, вариантность »; ~2 h
- Niveau 8 · Коллекции: выбор структуры данных и её цена — selon le plan de l’auteur, après « Обобщения: ограничения, реификация, вариантность »; ~2 h
- Niveau 8 · OCP: открыт для расширения, закрыт для изменения — selon le plan de l’auteur, après « SRP: одна причина для изменения »; ~2 h
- Niveau 9 · LINQ: отложенное выполнение, yield, IQueryable — selon le plan de l’auteur, après « Коллекции: выбор структуры данных и её цена »; ~2 h
- Niveau 9 · LSP: подтип обязан быть заменяемым — selon le plan de l’auteur, après « OCP: открыт для расширения, закрыт для изменения »; ~2 h
- Niveau 10 · ISP: клиента не заставляют зависеть от лишнего — selon le plan de l’auteur, après « LSP: подтип обязан быть заменяемым »; ~1,5 h
- Niveau 11 · DIP и внедрение зависимостей — selon le plan de l’auteur, après « ISP: клиента не заставляют зависеть от лишнего »; ~2,5 h
- Niveau 12 · Порождающие паттерны: кто и как создаёт объекты — selon le plan de l’auteur, après « DIP и внедрение зависимостей »; ~2 h
- Niveau 12 · Структурные паттерны: как собирать объекты в целое — selon le plan de l’auteur, après « DIP и внедрение зависимостей »; ~2 h
- Niveau 12 · Поведенческие паттерны: кто кого вызывает и когда — selon le plan de l’auteur, après « DIP и внедрение зависимостей », « Делегаты, лямбды, замыкания, события »; ~2 h
- Niveau 12 · Хост, DI на практике, конфигурация, логирование — selon le plan de l’auteur, après « DIP и внедрение зависимостей »; facultative; ~2 h
- Niveau 13 · Прикладные паттерны .NET: Repository, Options, CQRS, Result — selon le plan de l’auteur, après 2 de celles-ci : « Порождающие паттерны: кто и как создаёт объекты », « Структурные паттерны: как собирать объекты в целое », « Поведенческие паттерны: кто кого вызывает и когда »; ~2 h
- Niveau 13 · Minimal API: конвейер, привязка, валидация, ошибки — selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование »; facultative; ~2 h
- Niveau 13 · HttpClient, устойчивость и фоновые задачи — selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование », « async/await: что это и чего это не »; facultative; ~2 h
- Niveau 13 · EF Core без иллюзий — selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование », « LINQ: отложенное выполнение, yield, IQueryable »; facultative; ~2 h
- Niveau 14 · Финал: тестируемость и разговор об архитектуре вслух — selon le plan de l’auteur, après « Прикладные паттерны .NET: Repository, Options, CQRS, Result », « async/await: что это и чего это не »; ~2,5 h
- Niveau 14 · Выпуск в Azure: App Service, секреты, managed identity — selon le plan de l’auteur, après « Minimal API: конвейер, привязка, валидация, ошибки »; facultative; ~2 h
- Niveau 15 · Что нового в C# 13 и 14 и как об этом спрашивают — selon le plan de l’auteur, après « Финал: тестируемость и разговор об архитектуре вслух »; ~2 h
- Niveau 15 · Тесты сервиса: от модуля до HTTP — selon le plan de l’auteur, après « Хост, DI на практике, конфигурация, логирование », « Финал: тестируемость и разговор об архитектуре вслух »; facultative; ~2 h
Programme · 38 unités
| 1 | Что на самом деле происходит, когда вы жмёте F5 Описать путь от исходника до машинного кода: Roslyn → IL и метаданные → JIT (tier0 → tier1) → машинный код, и что меняют Debug и Release | ~2 h |
| 2 | Значимые и ссылочные типы: стек, куча и упаковка Предсказывать поведение кода при присваивании и передаче в метод для значимых и ссылочных типов, включая структуры в коллекциях и кортежи | ~2 h |
| 3 | Память и время жизни: сборщик мусора, IDisposable, using Объяснить поколенческую сборку и почему её цена определяется выжившими, а не мёртвыми объектами | ~2 h |
| 4 | class, struct, record: чем объявлять данные Выбирать между class, struct, record class, record struct и readonly record struct по вопросу «значение или сущность», а не по привычке | ~2 h |
| 5 | Равенство, хеш и сравнение: контракт, который легко нарушить Предсказывать, что сравнивает == и что сравнивает Equals, по статическому и настоящему типу | ~2 h |
| 6 | null: nullable-типы, ссылочная нулевая аннотация и что с этим делать Различать Nullable<T> и nullable reference types: что делает компилятор, что делает рантайм (особая упаковка) и что не делает никто | ~1,5 h |
| 7 | Сопоставление с образцом, кортежи, деконструкция Переписывать цепочки if/else с is и приведениями в switch-выражение и объяснять, почему порядок веток — часть смысла | ~2 h |
| 8 | Span, Memory, ref struct и как мерить Объяснять, что такое Span<T> и ReadOnlySpan<T>, и предсказывать, где срез даёт окно, а где копию | ~2 h |
| 9 | Строки: неизменяемость, интернирование, StringBuilder, Span Объяснять, что неизменяемость string даёт (безопасная передача, потокобезопасное чтение, надёжный ключ, интернирование) и чего не даёт (кэширования хеша, возможности стереть секрет) | ~1,5 h |
| 10 | Инкапсуляция и конструирование: объект, который нельзя собрать неправильно Объяснять инкапсуляцию через инварианты и проектировать тип, в котором невалидное состояние невыразимо | ~2 h |
| 11 | Наследование и полиморфизм: virtual, override, new, sealed Точно предсказывать, какая реализация вызовется при virtual/override, new и new virtual, через базовую и производную ссылку | ~2 h |
| 12 | Интерфейсы: контракт, явная реализация, DIM Проектировать интерфейс от потребителя и класть его рядом с потребителем, чтобы развернуть зависимость | ~1,5 h |
| 13 | Делегаты, лямбды, замыкания, события Объяснить устройство делегата (Target, Method, список вызова) и предсказать результат многоадресного вызова, в том числе с исключением | ~2 h |
| 14 | Обобщения: ограничения, реификация, вариантность Объяснить реификацию обобщений: отдельный машинный код для значимых T, общий для ссылочных, реальный тип в рантайме | ~2 h |
| 15 | Метаданные: рефлексия, атрибуты, генераторы кода Объяснить, что такое метаданные сборки и что делает рефлексия (Type, GetProperties, PropertyInfo.GetValue), и назвать её цену: поиск членов, позднее связывание, упаковка, негарантированный порядок | ~2 h |
| 16 | Коллекции: выбор структуры данных и её цена Выбирать коллекцию по горячей операции, изменяемости, нужному порядку и числу писателей, а не по привычке | ~2 h |
| 17 | LINQ: отложенное выполнение, yield, IQueryable Объяснить отложенное выполнение как вытягивание элементов по одному с конца цепочки и предсказывать его эффекты: повторную работу, изменения источника, захваченные переменные | ~2 h |
| 18 | Исключения: чем они являются и чем не являются Решать по контракту метода, что является исключением, а что — ожидаемым результатом | ~2 h |
| 19 | Данные на границе: JSON, файлы и потоки, даты и время Настроить System.Text.Json для внешнего контракта: один экземпляр JsonSerializerOptions, политика имён, строгость (required, RespectNullableAnnotations, RespectRequiredConstructorParameters из .NET 9), полиморфизм | ~2 h |
| 20 | async/await: что это и чего это не Объяснить, почему async освобождает поток на время ожидания, а не создаёт новый, и чем масштабируемость отличается от скорости | ~2,5 h |
| 21 | Конкурентность: lock, Lock, Interlocked, SemaphoreSlim, Channel, Parallel Объяснить гонку read-modify-write и предсказать, что произойдёт с общим полем, которое меняют несколько потоков | ~2 h |
| 22 | SRP: одна причина для изменения Сформулировать SRP через причину для изменения: один актор, приходящий с требованиями | ~2 h |
| 23 | OCP: открыт для расширения, закрыт для изменения Объяснить OCP через давление: одно изменение требований — правки в нескольких работающих модулях | ~2 h |
| 24 | LSP: подтип обязан быть заменяемым Сформулировать LSP через ожидания вызывающего кода и контракт базы: предусловия, постусловия, инварианты, история и исключения | ~2 h |
| 25 | ISP: клиента не заставляют зависеть от лишнего Объяснить ISP через механику зависимости: изменение толстого интерфейса пересобирает и ломает клиентов, которым изменившийся член не нужен | ~1,5 h |
| 26 | DIP и внедрение зависимостей Сформулировать обе части DIP и показать, почему вторая (контракт на языке потребителя и у потребителя) важнее | ~2,5 h |
| 27 | Порождающие паттерны: кто и как создаёт объекты Называть давление, которое снимает каждый порождающий паттерн, и случаи, когда хватает new | ~2 h |
| 28 | Структурные паттерны: как собирать объекты в целое Различать Adapter, Decorator, Facade и Proxy по намерению и по тому, меняется ли интерфейс | ~2 h |
| 29 | Поведенческие паттерны: кто кого вызывает и когда Узнавать давление, порождающее Strategy, Template Method, Observer, Command, State и Chain of Responsibility, на коде ENGAGE | ~2 h |
| 30 | Прикладные паттерны .NET: Repository, Options, CQRS, Result Аргументированно решать, нужен ли свой репозиторий поверх EF Core, и называть, чем обедняет общий IRepository<T> | ~2 h |
| 31 | Что нового в C# 13 и 14 и как об этом спрашивают Отнести возможность к версии языка: раньше C# 13, C# 13 (.NET 9) или C# 14 (.NET 10) — и не выдавать старое за новое | ~2 h |
| 32 | Финал: тестируемость и разговор об архитектуре вслух Связывать трудности тестирования с конкретными дефектами проектирования: new внутри метода, статика, DateTime.Now, new HttpClient(), файловая система | ~2,5 h |
| 33 | Хост, DI на практике, конфигурация, логирование Объяснить, что регистрируют Host.CreateApplicationBuilder и WebApplication.CreateBuilder, и собрать Program.cs как composition root с областями для Scoped-сервисов | ~2 h |
| 34 | Minimal API: конвейер, привязка, валидация, ошибки Предсказать источник каждого параметра обработчика (маршрут, строка запроса, тело, DI, [AsParameters]) и ответ на ошибку привязки | ~2 h |
| 35 | HttpClient, устойчивость и фоновые задачи Объяснить, почему new HttpClient() на каждый запрос исчерпывает порты, а вечный статический клиент не видит смены DNS, и выбрать между IHttpClientFactory и долгоживущим клиентом с PooledConnectionLifetime | ~2 h |
| 36 | EF Core без иллюзий Определять, какая часть LINQ-запроса уйдёт в SQL, а какая выполнится в памяти: Expression против Func, ToList в середине цепочки, непереводимые вызовы методов | ~2 h |
| 37 | Тесты сервиса: от модуля до HTTP Объяснить, какой класс дефектов ловит каждый уровень тестов сервиса, и выбрать между пирамидой и ромбом по тому, где живут ошибки | ~2 h |
| 38 | Выпуск в Azure: App Service, секреты, managed identity Опубликовать сервис ENGAGE (dotnet publish) и выбрать режим: framework-dependent, self-contained или ReadyToRun — с ценой каждого | ~2 h |
