C# / .NET C# и .NET: обзор языка, философия и дорожная карта курса
0%

C# и .NET: обзор языка, философия и дорожная карта курса

C# и .NET: обзор, философия и как учиться

C# — это статически типизированный, объектно-ориентированный язык с сильным уклоном в функциональные возможности, работающий на среде исполнения .NET (CLR — Common Language Runtime). Если проводить аналогию: CLR для C# — это то же, что JVM для Java или V8 для JavaScript. Вы пишете код на C#, компилятор (Roslyn) превращает его в промежуточный байт-код (IL, Intermediate Language), а во время запуска JIT-компилятор (Just-In-Time) переводит IL в машинный код под вашу платформу. Плюс есть режим AOT (Ahead-Of-Time), когда всё компилируется в нативный бинарник заранее.

Зачем это знать с первых строк? Потому что почти вся «магия» C# — сборка мусора, единая система типов, рефлексия, async/await, span-ы и производительность — это следствие устройства CLR. Понимая среду, вы перестаёте воспринимать язык как набор случайных правил.

Коротко об истории и «том самом» .NET

Важно не запутаться в названиях, потому что это частый источник боли для новичков:

  • .NET Framework (1.0–4.8) — старая, только-Windows платформа. Легаси. Новые проекты на ней не начинают.
  • .NET Core (1.0–3.1) — кросс-платформенная переработка с открытым исходным кодом.
  • .NET 5, 6, 7, 8, 9, … — с 2020 года команда убрала слово «Core» и объединила всё в единую линейку. Просто «.NET». Версии с чётным номером (.NET 8, .NET 10) — это LTS (Long-Term Support, 3 года поддержки), нечётные (.NET 9) — STS (18 месяцев).

В этом курсе мы используем .NET 8/9 и C# 12+ — это актуальный, кросс-платформенный, open-source стек (репозиторий github.com/dotnet). Правило для продакшена простое: сидите на актуальной LTS (.NET 8), обновляйтесь до следующей LTS в течение её жизненного цикла.

Как устроен путь от исходника до исполнения

Полезно один раз увидеть весь конвейер целиком — дальше в курсе многое станет понятнее.

  1. Компиляция. Roslyn превращает .cs в сборку (assembly) — файл .dll или .exe, содержащий IL и метаданные (описание типов). Метаданные — причина, по которой работают рефлексия, сериализаторы и IDE.
  2. Загрузка и JIT. При запуске CLR загружает сборки, а JIT-компилятор переводит IL в машинный код по мере вызова методов, оптимизируя под конкретный процессор.
  3. Исполнение под управлением CLR. Во время работы CLR предоставляет сборку мусора, проверку типов, обработку исключений и безопасность. Отсюда термин managed code.

Альтернативная ветка — AOT, где шаг JIT убран: всё компилируется в нативный код заранее (подробнее в статье про деплой).

Первая программа

Начиная с C# 9 доступны top-level statements — не нужны церемониальные class Program и static void Main. Минимальная программа — это буквально одна строка:

// Program.cs — всё, что нужно для «Hello, world»
Console.WriteLine("Привет, .NET!");

Запуск: dotnet run. Компилятор сам оборачивает это в метод Main. Такой лаконичный старт — визитная карточка современного C#: минимум шума, максимум сути. По ходу курса мы увидим, что весь язык эволюционирует в эту сторону.

Философия языка

C# развивается по нескольким устойчивым принципам, и понимание их помогает писать идиоматичный код:

  1. Безопасность типов и явность. Компилятор — ваш друг. Начиная с C# 8 включаемая опция nullable reference types заставляет компилятор отслеживать «может ли эта ссылка быть null», убирая целый класс NullReferenceException ещё до запуска.
  2. Прагматичная эволюция без ломки. Язык добавляет фичи (records, pattern matching, switch-выражения, primary constructors), но старый код продолжает компилироваться. Обратная совместимость — священная корова.
  3. Производительность как фича. Span<T>, Memory<T>, ValueTask, source generators, AOT — всё это про то, чтобы C# конкурировал с C++/Rust там, где нужно, не теряя удобства.
  4. Асинхронность в основе. async/await встроен в язык на уровне синтаксиса и пронизывает всю стандартную библиотеку и веб-фреймворки.
  5. Мультипарадигменность. ООП — фундамент, но LINQ, лямбды, immutable-records и pattern matching позволяют писать в функциональном стиле там, где это чище.

Где C# силён (ниши применения)

  • Веб-бэкенды и API — ASP.NET Core, один из самых быстрых веб-фреймворков в индустрии (см. бенчмарки TechEmpower). Minimal API и контроллеры, gRPC, GraphQL.
  • Облачные и микросервисные системы — first-class поддержка в Azure, но прекрасно живёт в AWS/GCP/Kubernetes. Отличная связка с Docker и OpenTelemetry.
  • Десктоп — WPF, WinUI, а кросс-платформенно — Avalonia и .NET MAUI.
  • Игры — Unity использует C# как основной язык скриптинга; Godot поддерживает C#.
  • Инструменты и CLI — быстрая разработка, single-file publish, AOT для мгновенного старта.
  • Data / ML — ML.NET, а также интеграция с Python-экосистемой.
  • IoT / embedded — .NET nanoFramework, .NET IoT.

Где C# исторически слабее: системное программирование самого нижнего уровня (там всё же Rust/C), фронтенд в браузере (Blazor WebAssembly существует, но JS/TS доминирует).

Экосистема: BCL, NuGet и инструменты

Язык — это лишь верхушка. Сила .NET — в зрелой экосистеме:

  • BCL (Base Class Library) — огромная стандартная библиотека: коллекции, LINQ, работа с сетью и файлами, System.Text.Json, криптография, DI, конфигурация. Многое, ради чего в других языках тянут пакеты, в .NET уже есть «из коробки» и высокого качества.
  • NuGet — менеджер пакетов (nuget.org). Сотни тысяч библиотек: EF Core, Serilog, Polly, FluentValidation, xUnit и т.д.
  • dotnet CLI — единый инструмент для создания, сборки, запуска, тестов и публикации.
  • ASP.NET Core, EF Core, ML.NET, Blazor, MAUI — официальные фреймворки под веб, доступ к данным, ML, web-UI и кросс-платформенный UI соответственно.

Всё это — open-source под .NET Foundation, разрабатывается публично на GitHub.

Распространённые заблуждения

  • «C# только для Windows». Уже давно нет: .NET кросс-платформенный, львиная доля бэкендов на нём работает в Linux-контейнерах.
  • «C# медленный, потому что managed». Современный .NET — один из самых быстрых управляемых рантаймов; с Span<T>, AOT и продуманным GC он конкурирует за перф там, где раньше был только C++.
  • «C# — тяжеловесный enterprise-язык». Top-level statements, records, pattern matching и Minimal API делают его лаконичным; boilerplate давно ушёл.
  • «Нужна дорогая Visual Studio». SDK, компилятор и отладка бесплатны и работают в VS Code, Rider (платный, но не обязателен), Neovim.

Дорожная карта курса

Курс построен так, чтобы провести вас от синтаксиса до эксплуатации продакшн-сервиса. Читайте по порядку — каждая статья опирается на предыдущую.

  1. Установка и тулчейн — SDK, dotnet CLI, NuGet и Central Package Management, структура решения, форматтер, анализаторы, IDE.
  2. Основы языка — типы (value vs reference), nullable, записи, pattern matching, коллекции, LINQ, модель памяти и GC.
  3. Идиоматика и ошибки — исключения vs result-паттерн, IDisposable/using, паттерны и антипаттерны, code style.
  4. Конкурентность — async/await, TAP, Task vs ValueTask, CancellationToken, Channels, IAsyncEnumerable, ловушки и дедлоки.
  5. Тестирование — xUnit, FluentAssertions, моки, property-based, Testcontainers, WebApplicationFactory, покрытие, тест-пирамида.
  6. Архитектура и продакшн — слоистая и гексагональная архитектура, DI, Options pattern, EF Core, устойчивость.
  7. Деплой и наблюдаемость — publish, Docker, health checks, логи/метрики/трейсинг через OpenTelemetry, перф-профилирование.
  8. SDLC и лучшие ресурсы — жизненный цикл, CI/CD, релизная стратегия, безопасность зависимостей, курированный список источников.

Мини-словарь: термины, которые встретятся в курсе

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

  • CLR — Common Language Runtime, среда исполнения: JIT, GC, безопасность типов.
  • BCL — стандартная библиотека (System.*).
  • IL — промежуточный байт-код, в который компилируется C#.
  • GC — сборщик мусора, автоматически освобождает память.
  • JIT / AOT — компиляция в машинный код во время запуска / заранее.
  • NuGet — менеджер пакетов и его реестр.
  • TFM (Target Framework Moniker) — целевая платформа проекта, напр. net9.0.
  • SDK — набор инструментов разработчика; runtime — то, что нужно для запуска.
  • assembly (сборка) — единица компиляции и развёртывания (.dll).
  • managed code — код, исполняемый под управлением CLR.

Каждый из них мы раскроем в соответствующих статьях; здесь важно узнать их «в лицо».

Как учиться, чтобы «уметь применять»

  • Пишите код руками. Не копируйте бездумно — набирайте, ломайте, чините. Держите открытый scratch-проект (dotnet new console), куда вставляете примеры из статей.
  • Читайте ошибки компилятора и анализаторов буквально. В C# они точны и часто содержат готовое решение. Включите nullable и TreatWarningsAsErrors — пусть машина учит вас дисциплине.
  • Идите вглубь стандартной библиотеки. BCL (Base Class Library) огромна и качественна. Прежде чем тянуть NuGet-пакет, проверьте — возможно, System.* уже умеет это.
  • Наблюдайте за исполнением. Ставьте брейкпоинты, смотрите на async-стектрейсы, используйте dotnet-counters. Понимание «что происходит в рантайме» отличает джуна от сеньора.
  • Опирайтесь на первоисточники. Официальная документация learn.microsoft.com/dotnet — образцовая; блог команды devblogs.microsoft.com/dotnet объясняет «почему».

Порядок важен: статьи выстроены как лестница, каждая опирается на предыдущую. Если вы уже опытны в другом языке, всё равно не пропускайте «Основы» и «Конкурентность» — именно там прячется специфика C#, на которой спотыкаются даже сеньоры из других экосистем. Не торопитесь: лучше разобрать одну статью с кодом в руках, чем пробежать три глазами.

Сквозной пример курса

Чтобы теория не висела в воздухе, через статьи проходит один сквозной пример — маленький сервис заказов (OrderService). Мы будем возвращаться к нему в разных разрезах:

  • в «Основах» — как смоделировать Order, Money, Customer записями и pattern matching;
  • в «Идиоматике» — как обрабатывать «корзина пуста» и «нет на складе» (Result против исключений);
  • в «Конкурентности» — как параллельно дёргать внешние API и стримить заказы через IAsyncEnumerable;
  • в «Тестировании» — как покрыть его юнитами и интеграционными тестами с реальной БД;
  • в «Архитектуре» — как разложить по слоям, подключить EF Core и DI;
  • в «Деплое» — как контейнеризовать, добавить health checks, логи, метрики и трейсы.

Так вы увидите не разрозненные фичи, а как они складываются в один работающий продукт.

Что вы будете уметь в конце

  • Настроить с нуля решение с CPM, анализаторами и CI, соответствующее индустрии.
  • Писать идиоматичный современный C# с nullable, records и pattern matching.
  • Осознанно работать с async/await, не создавая дедлоков и утечек.
  • Покрывать код тестами на всех уровнях пирамиды.
  • Проектировать сервис по слоям с DI, конфигурацией и EF Core.
  • Собирать, контейнеризовать, деплоить и наблюдать сервис в проде.

Ключевые источники на весь курс

Что дальше

Установка и тулчейн — соберём рабочее окружение, разберёмся с dotnet CLI, структурой проекта и инструментами качества.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов