Процесс компиляции C# и Common Intermediate Language (CIL)
Что такое CIL?
CIL (Common Intermediate Language) — это промежуточный язык, в который компилируется исходный код C# перед выполнением. Он стандартизирован в рамках CLI (Common Language Infrastructure) и раньше назывался MSIL (Microsoft Intermediate Language).
Программы на C#, VB.NET, F#, и других языках .NET сначала компилируются в CIL, а не напрямую в машинный код.
Этапы компиляции C# программы
1. Написание кода
Код пишется на C# в файле с расширением .cs
.
class Program {
static void Main() {
Console.WriteLine("Hello, world!");
}
}
2. Компиляция в CIL (файлы .dll
или .exe
)
С помощью компилятора csc
(C# Compiler) код преобразуется в CIL, который сохраняется в сборке — файле .dll
(библиотека) или .exe
(исполняемый файл).
csc Program.cs
# Создаст Program.exe
На этом этапе код ещё не исполняется. Он просто хранится в виде CIL-инструкций в сборке.
3. Загрузка CLR и JIT-компиляция
Когда ты запускаешь .exe
или подключаешь .dll
:
- .NET CLR (Common Language Runtime) загружает сборку.
- JIT-компилятор (Just-In-Time) преобразует CIL в машинный код, который понимает конкретный процессор (x64, ARM и т.д.).
- После этого программа выполняется.
.NET 6+ может использовать ReadyToRun (R2R) или AOT (Ahead-of-Time) компиляцию, чтобы ускорить запуск.
Что находится внутри .dll и .exe сборок?
Компонент | Описание |
---|---|
CIL-код | Промежуточный код, который исполняется CLR через JIT-компиляцию |
Метаданные | Информация о типах, методах, свойствах, пространствах имён и т.п. |
Манифест сборки | Информация о версии, зависимостях, культуре, имени сборки и т.п. |
Ресурсы (опц.) | Встроенные изображения, строки, локализация и другие данные |
Символы отладки | (если присутствует .pdb ) — соответствие строк кода и CIL-инструкций |
Пример: как выглядит CIL
Пример C#:
int Add(int a, int b) => a + b;
CIL (упрощённо):
.method public hidebysig static int32 Add(int32 a, int32 b) cil managed
{
.maxstack 2
ldarg.0
ldarg.1
add
ret
}
ldarg.0
— загрузка первого аргумента на стек
add
— сложение двух верхних значений на стеке
ret
— возврат результата
Какие технологии взаимодействуют с CIL?
Технология | Роль в процессе |
---|---|
Roslyn |
Компилятор C#, генерирует CIL |
CoreCLR / CLR |
Исполняет CIL, использует JIT |
ILDasm |
Разборщик: показывает CIL из сборки |
ILSpy , dnSpy |
Декомпиляторы: показывают CIL и C# |
Mono |
Кроссплатформенная реализация CLR |
dotnet publish |
Компиляция и упаковка для публикации |
Почему используется CIL?
- ✅ Независимость от архитектуры: один
.dll
или.exe
может выполняться на разных системах - ✅ Поддержка многих языков (VB.NET, F#, C++/CLI) в рамках одного рантайма
- ✅ Оптимизация на стадии JIT под конкретную платформу
Резюме
Этап | Что происходит |
---|---|
1 | Код пишется на C# |
2 | Компилируется в CIL → .dll/.exe |
3 | CLR загружает сборку |
4 | JIT преобразует CIL в машинный код |
5 | Код исполняется на системе |
Полезные команды
# Посмотреть CIL код
ildasm Program.exe
# Декомпиляция через ILSpy
ilspy Program.dll
# Компиляция проекта
dotnet build
# Публикация со сборкой ReadyToRun
dotnet publish -r win-x64 -p:PublishReadyToRun=true