How it works
The explanation, with examples you can run.
What IL looks like
Take a tiny method:
static int Add(int a, int b) => a + b;In a Release build its IL is four instructions: ldarg.0 pushes a onto the evaluation stack, ldarg.1 pushes b, add pops both and pushes their sum, and ret returns the value on top of the stack. There are no registers and no assumptions about word size or calling convention. You can see the IL for any method with a disassembler such as ILSpy, or with the IL viewer in Rider or Visual Studio extensions.
The format is a standard, ECMA-335 (the Common Language Infrastructure). It defines IL, the metadata tables, and the common type system that every .NET language agrees on. That is why F#, VB and C# libraries interoperate without bindings.
What the CLR does with it
When a process starts, the host (the dotnet executable or your app's native launcher) loads the runtime, which then:
- Loads assemblies on demand, reading their metadata to find types and their dependencies.
- Lays out types: computes field offsets, builds method tables (the per-type structure used for virtual calls and type checks), and runs static constructors when a type is first used.
- Verifies and compiles: the first call to a method goes through a stub that asks the JIT to compile its IL; later calls go straight to the machine code.
- Manages the process: allocates objects and collects them, runs the thread pool, unwinds the stack for exceptions, and enforces type safety at casts.
Because compilation happens at run time, the same assembly runs on x64 and Arm64, on Linux, Windows and macOS. The cost is that the first calls to every method pay for compilation, which the next topic is about.
Metadata makes the ecosystem work
Every assembly carries a full description of itself, so code can inspect types it has never seen at compile time:
foreach (var m in typeof(string).GetMethods().Take(3)) Console.WriteLine(m.Name);Reflection, System.Text.Json, ASP.NET Core model binding, dependency injection containers and test frameworks all rely on this. It is also what Native AOT has to work around: when there is no JIT at run time, code that generates new types or methods on the fly cannot work, and code that reflects over types the compiler couldn't see may find them trimmed away.
Versions to know
.NET (formerly .NET Core) is the cross-platform runtime; .NET Framework 4.8 is the older, Windows-only one, still maintained but not getting new features. New releases ship every November; even-numbered ones are long-term support (three years), odd-numbered ones are standard-term (two years). .NET 10 shipped in November 2025 with C# 14.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.