This lesson is not translated yet – the Russian original is below.
Прежде чем писать первую строчку, стоит разобраться, что вообще произойдёт, когда вы нажмёте «запустить». Иначе половина сообщений об ошибках будет выглядеть как магия: непонятно, кто их пишет – редактор, компилятор или сама программа.
Язык и платформа – это разные вещи
C# – это язык. Набор правил, по которым вы записываете свои мысли: как объявить переменную, как описать условие, где ставить точку с запятой. Язык – это текст, сам по себе он ничего не делает.
.NET – это платформа. Всё, что нужно, чтобы написанный текст заработал: компилятор, среда выполнения, большая библиотека готового кода (работа с файлами, сетью, датами, строками) и инструменты командной строки.
На .NET пишут не только на C#. Есть ещё F# и Visual Basic – платформа одна, языки разные. Просто C# на ней самый распространённый, и большинство примеров в интернете именно на нём.
Отсюда практическое следствие: когда вы ищете ответ на вопрос, полезно понимать, о чём именно вы спрашиваете. «Как в C# написать цикл» – вопрос про язык. «Как в C# прочитать файл» – на самом деле вопрос про библиотеку .NET, потому что в самом языке никакого чтения файлов нет.
Что происходит, когда вы жмёте «запустить»
В Python исходник читается прямо во время работы. В C++ компилятор заранее превращает текст в машинные команды. C# идёт третьим путём: компилятор есть, но машинный код он не выдаёт. Между ними появляется промежуточная остановка.
Компилятор переводит ваш C# в IL – промежуточный язык (Intermediate Language).В документации встречаются ещё два названия того же самого: CIL (Common Intermediate Language) и устаревшее MSIL. Это одно и то же. Это уже не
текст для человека, но ещё и не команды процессора. IL складывается в сборку: файл .dll
или .exe.
Когда сборку запускают, за дело берётся JIT-компилятор (Just-In-Time, «точно в срок»). Он переводит IL в настоящие машинные команды – но не весь сразу, а по мере надобности: вызвали метод впервые, его скомпилировали, дальше он работает уже готовым.
Зачем эта лишняя остановка
Кажется, что проще было бы сразу компилировать в машинный код. Промежуточный шаг даёт две вещи, ради которых всё и затевалось.
Одна сборка работает везде. Набор машинных команд у процессора Intel и у процессора Apple разный. Программу на C++ приходится собирать отдельно под каждую платформу. Сборка с IL – одна: JIT на месте разберётся, куда её приземлять.
JIT знает то, чего не знает компилятор. Обычный компилятор собирает программу заранее и вынужден рассчитывать на средний процессор. JIT работает в момент запуска – он видит конкретную машину и может использовать именно её инструкции.
Первый запуск программы на .NET чуть медленнее последующих: JIT в это время компилирует то, до чего дошло выполнение. Если вы замеряете скорость, первый прогон обычно выбрасывают.
CLR: что рантайм делает за вас
Среда выполнения называется CLR – Common Language Runtime. Кроме запуска IL она берёт на себя работу, которую в языках вроде C приходится делать руками.
Убирает мусор. Вы создаёте объекты, но нигде не пишете, когда их удалить. За этим следит сборщик мусора: он находит объекты, до которых из программы уже никак не добраться, и освобождает память. Забыть освободить память в C# практически невозможно.
Проверяет типы. Если переменная объявлена как число, положить в неё строку не выйдет ни при компиляции, ни во время работы. Целый класс ошибок отсекается до того, как программа запустится.
Проверяет границы. Обращение к одиннадцатому элементу массива из десяти не прочитает чужую память, как это было бы в C, а честно бросит исключение с понятным текстом.
За это платят: программа на C# тратит больше памяти, чем аналог на C, и время от времени отвлекается на сборку мусора. Для подавляющего большинства задач обмен выгодный – но именно поэтому операционные системы и драйверы на C# не пишут.
.NET Framework, .NET Core и просто .NET
В поиске вы наткнётесь на три названия, и разница между ними существенная.
| Название | Годы | Что это |
|---|---|---|
| .NET Framework | 2002 – 2019 | Первая версия. Только Windows. Развитие остановлено, 4.8 – последняя |
| .NET Core | 2016 – 2020 | Переписанная кроссплатформенная версия. Название дожило до 3.1 |
| .NET | с 2020 | Продолжение .NET Core, начиная с версии 5. Просто «.NET», без суффикса |
Нумерацию начали с пятёрки, чтобы не пересекаться с .NET Framework 4.8 и заодно показать: это одна ветка, а не две параллельные.
Если ответ на Stack Overflow написан для .NET Framework, он может не подойти: часть библиотек в новой платформе называется иначе, а часть работает только на Windows. Смотрите на дату – всё старше 2020 года стоит перепроверять.
Где на этом пишут
C# начинали как язык для настольных программ под Windows, но с тех пор он расползся:
- веб-сервисы и API – ASP.NET Core, самое частое применение сегодня;
- игры – Unity, один из главных игровых движков индустрии, использует именно C#;
- мобильные и настольные приложения – .NET MAUI и Avalonia: одна кодовая база на несколько систем;
- утилиты командной строки – то, с чего мы начнём в следующем уроке.
Ничего из этого не потребуется прямо сейчас. Первые уроки пройдут в консоли: она ничем не отвлекает и показывает результат сразу.