Belajar C# - Konsep Dasar & Arsitektur Utama
Series/Belajar C#/Episode 2
Episode 2 of 23

Belajar C# - Konsep Dasar & Arsitektur Utama

Episode ini membedah cara kerja C# di balik layar: kompilasi ke Intermediate Language, eksekusi oleh CLR dengan JIT dan garbage collector, konsep assembly, metadata, dan manifest, serta struktur solution dan project .NET beserta alur build-nya.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Pendahuluan

Di episode 1 kalian paham sejarah C# dan mengapa bahasa ini dibutuhkan. Sekarang kita turun satu level: bagaimana sebenarnya kode C# dijalankan di mesin. Ini bukan materi akademis murni — memahami arsitektur runtime akan membantu kalian saat debugging, mengoptimasi performa, dan memilih struktur project yang tepat.

Bayangkan alur kerja kalian hari ini: menulis kode, menekan dotnet run, dan hasilnya muncul. Di antara kedua momen itu terjadi banyak hal yang selama ini tersembunyi: source code dikompilasi, di-load sebagai assembly, dikompilasi ulang oleh JIT, lalu dieksekusi dengan bantuan garbage collector.

Episode 2 ini membedah alur tersebut langkah demi langkah: kompilasi ke IL, eksekusi oleh CLR, konsep assembly dan metadata, struktur project .NET, serta alur build dan eksekusi dengan dotnet CLI.

Jangan khawatir jika bagian ini terasa abstrak. Beberapa konsep akan lebih jelas saat kalian melihat hasil build secara nyata di bagian akhir episode. Yang penting sekarang adalah memetakan peta mental: apa yang terjadi dari source code sampai aplikasi berjalan.

Untuk memudahkan, anggap proses ini seperti rantai produksi: source code adalah bahan mentah, Roslyn adalah mesin pengolah yang mencetak IL, CLR adalah pengawas yang mengatur pekerja, dan garbage collector adalah tim kebersihan yang terus merapikan area kerja. Saat semuanya berjalan, kalian hanya melihat hasil akhirnya: aplikasi berjalan mulus. Analogi ini akan dipakai berulang di episode-episode selanjutnya.

Dari Source Code ke IL

Peran Compiler Roslyn

Saat kalian menjalankan dotnet build, compiler C# bernama Roslyn menerjemahkan source code menjadi Intermediate Language (IL) — kode byte yang tidak spesifik ke satu CPU. IL inilah yang memungkinkan C# berjalan di Windows, Linux, dan macOS tanpa menulis ulang kode. Proses kompilasi juga menghasilkan metadata yang mendeskripsikan semua tipe, method, dan field dalam kode kalian.

Alur kompilasi dan eksekusi
Program.cs --Roslyn--> IL + metadata --CLR--> JIT --> kode mesin

Managed Runtime: CLR, JIT, dan Garbage Collector

Eksekusi oleh CoreCLR

Hasil kompilasi berupa assembly dijalankan oleh Common Language Runtime (CLR), yang dalam implementasi modern disebut CoreCLR. CLR adalah managed runtime: dia mengelola eksekusi kode, menegakkan type safety saat runtime, dan menyediakan layanan seperti exception handling dan keamanan akses kode.

JIT Compiler

Pada saat eksekusi, metode yang dipanggil diterjemahkan dari IL ke kode mesin asli oleh Just-In-Time compiler (JIT). JIT hanya meng-compile metode yang benar-benar dipanggil, dan di episode 15 kita akan melihat fitur tiered compilation yang membuat JIT semakin cepat seiring berjalannya program.

Keuntungan pendekatan ini adalah portabilitas murni: satu assembly yang sama bisa dieksekusi di arsitektur CPU yang berbeda. IL di-compile ulang ke instruksi native yang sesuai dengan prosesor tempat aplikasi berjalan, tanpa perlu mengubah kode sumber sama sekali.

Garbage Collector

CLR juga menjalankan garbage collector (GC) generasional yang membagi heap menjadi generasi 0, 1, dan 2. Objek yang masih hidup cukup lama akan dipromosikan ke generasi berikutnya, sehingga GC bisa memfokuskan kerjanya pada objek muda yang paling sering tidak terpakai. Inilah kenapa developer C# tidak perlu membebaskan memori secara manual.

Ketika aplikasi berjalan, GC bekerja di latar belakang: mengalokasikan memori untuk objek baru, melacak referensi, dan mengklaim kembali memori dari objek yang sudah tidak direferensikan. Akibatnya, kesalahan umum seperti double free dan use-after-free yang lazim di C dan C++ praktis mustahil terjadi di C#.

Assembly, Metadata, dan Manifest

Hasil build berupa file .dll yang disebut assembly. Assembly menyimpan tiga hal: IL, metadata tipe, dan manifest yang berisi identitas assembly, versi, dan daftar dependency. Pada .NET modern, versi SDK dikodekan sebagai assembly informational version dan kalian bisa memeriksanya dengan tooling:

Cek assembly project
dotnet build -c Release
ls bin/Release/net8.0/

Perintah dotnet build -c Release menghasilkan assembly di folder bin/Release/net8.0. Kalian akan melihat file *.dll berisi kode aplikasi, *.deps.json berisi daftar dependency, dan *.runtimeconfig.json berisi pengaturan runtime. Ketiganya wajib ada saat publish. Struktur tiga file ini adalah alasan kenapa project .NET bisa langsung dijalankan dengan dotnet run tanpa konfigurasi tambahan.

Dari sisi eksekusi, assembly inilah yang dibaca CLR setiap kali kalian menjalankan aplikasi. dotnet run sebenarnya adalah rangkaian build lalu eksekusi: project di-compile dulu, assembly hasilnya dijalankan, dan jika tidak ada perubahan kode, hasil build yang sudah ada yang dipakai. Ini menjelaskan kenapa percobaan pertama terasa lebih lambat daripada percobaan berikutnya.

Struktur Proyek .NET

Solution, Project, dan Folder src/tests

Project .NET besar diorganisir dengan solution (file .sln) yang menampung banyak project. Konvensi umum: folder src untuk kode aplikasi dan tests untuk kode pengujian. Buat struktur standar:

Membuat solution dengan dua project
dotnet new sln -n Toko
dotnet new console -n Toko.App -o src/Toko.App
dotnet new xunit -n Toko.Tests -o tests/Toko.Tests
dotnet sln Toko.sln add src/Toko.App tests/Toko.Tests

Perintah dotnet sln Toko.sln add src/Toko.App mendaftarkan project ke solution. Struktur ini yang akan kita pakai mulai episode 4, dan detail testing-nya kita bahas di episode 10.

Paket NuGet dan SDK-style Projects

Dependency ditambahkan lewat NuGet, manager paket resmi .NET. Project modern memakai format SDK-style: file .csproj yang singkat, otomatis memperhitungkan semua file .cs di folder. Tambah dependency dengan:

Menambah paket NuGet
dotnet add src/Toko.App package Newtonsoft.Json

Perintah dotnet add ... package Newtonsoft.Json mengunduh paket dan mencatatnya di file project. Seluruh transitive dependency akan otomatis diselesaikan saat build. NuGet menjadi sumber ratusan ribu library yang bisa langsung dipakai — inilah ekosistem yang membuat C# sangat produktif.

Alur Build dan Eksekusi dengan dotnet CLI

Build, Run, dan Publish

Seluruh lifecycle project dijalankan lewat dotnet CLI. Perintah yang paling sering dipakai:

  • dotnet build: meng-compile project dan menghasilkan assembly.
  • dotnet run: build lalu langsung menjalankan aplikasi.
  • dotnet test: build dan menjalankan seluruh unit test.
  • dotnet publish: memproduksi output siap deploy dengan dependency lengkap.
Tiga perintah inti dotnet
dotnet build -c Release
dotnet run --project src/Toko.App
dotnet publish src/Toko.App -c Release

Perintah dotnet publish -c Release menghasilkan folder output yang berisi aplikasi dan semua dependency-nya — ini yang nanti kita bungkus ke Docker di episode 19.

Penutup

Inti yang harus dibawa pulang:

  • Roslyn meng-compile C# ke IL, lalu CLR menjalankannya lewat JIT.
  • Garbage collector membebaskan memori secara otomatis dengan model generasional.
  • Assembly menyimpan IL, metadata, dan manifest, plus file deps dan runtimeconfig.
  • Solution menampung banyak project; konvensi src dan tests menjaga kerapian.
  • Lifecycle project dijalankan lewat build, run, test, dan publish.

Di episode 3 selanjutnya kita akan mulai menulis kode sungguhan: sintaks dasar dan struktur program — deklarasi variabel dengan var dan const, tipe data dasar, operator, control flow, serta program console pertama yang lengkap. Persiapkan editor kalian!