Aim
To install and verify a complete C# tool-chain (.NET SDK with the Roslyn compiler) and execute a first console program, confirming that source code travels the full managed-execution pipeline: C# source → CIL → JIT → native machine code.
Theory
C# is a statically typed, object-oriented language whose compilation model differs fundamentally from C/C++. The Roslyn compiler (csc) does NOT emit native machine code; it emits CIL (Common Intermediate Language) — a stack-based, CPU-neutral instruction set — packaged into a managed assembly (a .dll containing IL, rich metadata and a manifest). At run time the CLR (Common Language Runtime) loads the assembly, verifies the IL for type safety, and RyuJIT (the Just-In-Time compiler) translates each method into native code the first time it executes, caching the result for subsequent calls. This two-stage design buys three things: portability (the same IL runs on Windows, Linux and macOS), safety (array bounds checks, managed references, garbage collection) and runtime optimisation (tiered compilation recompiles hot methods aggressively). Every C# program needs exactly one entry point — a static Main method — which the CLR locates through assembly metadata, not through a linker convention as in C.
Requirements
- .NET SDK 8.0 (LTS) or later — verify with
dotnet --version - Any editor: Visual Studio 2022, VS Code + C# Dev Kit, or plain Notepad
- Alternatively, the built-in RUN CODE compiler on this platform (no installation needed)
Procedure
- Install the .NET SDK and confirm the tool-chain:
dotnet --versionanddotnet --list-sdks. - Scaffold a project:
dotnet new console -n Lab0Setup, thencd Lab0Setup. - Replace the generated
Program.cswith the code shown here. - Compile and execute in one step:
dotnet run. Internally this runsdotnet build(producingbin/Debug/net8.0/Lab0Setup.dll) and then hosts the assembly in the CLR. - Optional: inspect the IL with
ildasm(Windows) or thedotnet-ildasmtool and findcall void [System.Console]System.Console::WriteLine(string)— visible proof of the two-stage model.
Explanation of the Code
using System;imports theSystemnamespace soConsolecan be used without full qualification (System.Console).class Program— in C# ALL executable code must live inside a type; there are no free functions as in C.static void Main()is the entry point.staticmeans the CLR can invoke it without instantiatingProgram;voidmeans no exit code is returned (anintreturn type is also legal and becomes the process exit code).Console.WriteLine(...)is a static method that writes its string plusEnvironment.NewLineto the standard output stream (stdout). Two calls produce two separate lines.
Expected Output
C# Lab compiler is ready.
Run each practical using the RUN CODE button.
Note
The original experiment list contained a duplicate palindrome practical; it is included only once in this lab to keep the sequence clean.
🎯 Viva Questions
- What is CIL/MSIL? — The CPU-neutral intermediate language Roslyn emits; the CLR's JIT converts it to native code at run time.
- Difference between the .NET SDK and the .NET Runtime? — The SDK contains compilers and the
dotnetCLI for building; the runtime only executes already-built assemblies. - What is an assembly? — A compiled unit (
.dll/.exe) containing IL, metadata and a manifest; the unit of deployment and versioning in .NET. - Why must Main be static? — So the CLR can call it directly without constructing an object first.
- What does JIT give us over ahead-of-time compilation? — A portable shipped binary plus runtime optimisations (tiered compilation); .NET also offers AOT via
dotnet publishwhen startup time matters. - Which method writes a line to standard output? —
System.Console.WriteLine, which appendsEnvironment.NewLineautomatically.