Vezérlőpult
A3. A .NET nyelvcsalád és futtatókörnyezet · Bevezetés, környezet, Git

A blokk · Bevezetés, környezet, Git · 3. tananyag

A .NET nyelvcsalád és futtatókörnyezet

A programod egy szövegfájl — a processzor viszont csak gépi kódot ért. Ez a fejezet arról szól, mi történik a kettő között: megismered a CLR, az IL, a JIT és a GC betűszavakat, és kimondjuk a .NET-világ alaptörvényét: itt minden objektum.

2 tanóraElmélet + gyakorlatBöngészős kódolás (sharplab.io)

Tanulási célok

1A probléma: a gép nem ért szöveget

A processzor csak gépi kódot hajt végre: az adott processzortípus saját, számokból álló utasításkészletét. A Console.WriteLine("Szia!"); sor a gépnek semmit sem jelent — valamin keresztül le kell fordítani.

Két hagyományos megoldás létezik, és mindkettőnek ára van:

MegközelítésHogyan működik?PéldaÁr
Fordítás (compile)a teljes programot előre gépi kódra fordítjukC, C++gyors futás, de a kész program csak egyféle gépen fut
Értelmezés (interpret)egy program soronként olvassa és hajtja végreklasszikus Pythonbárhol fut, de lassabb

A .NET (és a Java) egy harmadik utat választott: a kettő kombinációját.

2A .NET útja: két lépésben a processzorig

1 · FORDÍTÁSKOR 2 · FUTÁSKOR Program.cs a forráskódod C#-fordító (Roslyn) program.dll IL — köztes nyelv CLR JIT-fordító GC · típusok · kivételek CPU gépi kód Az IL platformfüggetlen: ugyanaz a .dll fut Windowson, Linuxon és macOS-en — mindenhol a helyi CLR fordítja az adott gép gépi kódjára.
A forráskód útja a processzorig: fordításkor IL készül, futáskor a CLR JIT-fordítója dolgozik.

1. lépés — fordításkor: a C#-fordító (Roslyn) a forráskódot nem gépi kódra, hanem IL-re (Intermediate Language — köztes nyelv) fordítja. Ez egy .dll fájlba kerül. Az IL még nem kötődik processzortípushoz — „félkész”, de már gépiesen feldolgozható kód.

2. lépés — futáskor: amikor elindítod a programot, a CLR (Common Language Runtime — közös nyelvi futtatókörnyezet) betölti az IL-kódot, és a JIT-fordító (Just-In-Time — „éppen időben”) az éppen futtatandó részeket az adott gép processzorára fordítja.

ℹ️ MIÉRT JÓ EZ?

Az IL platformfüggetlen: ugyanaz a .dll fut Windowson, Linuxon, macOS-en — mindenhol a helyi CLR fordítja gépi kódra. Ráadásul a JIT a tényleges processzort ismeri, így ahhoz igazíthatja a kódot.

⚠️ FONTOS KÖVETKEZMÉNY

A C#-programod futtatásához a célgépen ott kell lennie a .NET futtatókörnyezetnek (runtime). Ezért látod majd telepítéskor külön az „SDK” (fejlesztéshez) és a „Runtime” (csak futtatáshoz) csomagokat — erről az A4 fejezetben lesz szó.

3Mit csinál még a CLR? — a GC és társai

A CLR nem csak JIT-fordít. Futás közben végig ott áll a programod mögött:

CLR-szolgáltatásMit jelent?
JIT-fordításIL → gépi kód, futás közben, az adott processzorra
Memóriakezelés + GChelyet ad az objektumoknak, és automatikusan felszabadítja, amire már nincs szükség
Típusbiztonságnem engedi, hogy egy string-et számként használj — a hibát elkapja
Kivételkezelésa futási hibák szabályozott jelzése (a K blokkban tanuljuk)

A GC — a szemétgyűjtő

A GC (Garbage Collector — szemétgyűjtő) a CLR takarítója. C-ben és C++-ban a programozó kézzel kéri és adja vissza a memóriát — és ha elfelejti visszaadni, a program egyre többet fogyaszt (ez a memóriaszivárgás). C#-ban ezt a GC intézi:

  1. a program objektumokat hoz létre → a CLR memóriát ad nekik;
  2. egy idő után egyes objektumokra már semmi sem hivatkozik — elérhetetlenek;
  3. a GC időnként végignézi a memóriát, és az elérhetetlen objektumok helyét felszabadítja.
💡 HASONLAT

Egy étteremben nem a vendég mosogat: eszik, otthagyja a tányért, és a személyzet időnként leszedi az elhagyott asztalokat. A GC a személyzet — nem kell szólni neki, magától jár körbe.

4„Minden objektum” — a System.Object

Most, hogy tudjuk, mi fut (IL a CLR-en), kimondhatjuk a .NET-világ alaptörvényét:

ℹ️ ALAPTÖRVÉNY

A .NET-ben minden típus egyetlen közös ősből, a System.Object-ből származik.

System.Object értéktípusok int · double · bool · char · … string szöveg (System.String) saját osztályok Jatekos · Szoba · … (H blokk)
Minden út a System.Object-hez vezet — az egész típusrendszer egyetlen családfa.

Az objektumorientált világban minden objektumnak metódusai és tulajdonságai vannak, lehetnek. Látni fogjuk ezt a C#-nál is, hiszen itt tényleg minden objektum, már egy egyszerűnek tűnő adattípus is.

int szam = 42;
szam.ToString();   // "42"  — a szám szöveggé alakítja magát
szam.GetType();    // System.Int32 — megmondja a saját típusát

Az int valójában csak álnév (alias) a System.Int32 típusra — ahogy a string a System.String-re. A rövid nevet gépeljük, de a háttérben mindig a System.… típus áll.

⚠️ ELŐREUTALÁS

Attól, hogy minden az Object leszármazottja, még nem viselkedik minden típus ugyanúgy: van értéktípus (pl. int) és referenciatípus (pl. string, saját osztályok), és a különbség a másolásnál számít majd. Ezt a H blokkban vesszük — most elég annyi: mindkettő az Object családfájában van.

5A nyelvcsalád: egy futtatókörnyezet, több nyelv

Az IL-nek van egy szép következménye: nem csak C#-ból lehet IL-t készíteni. A .NET-nek több nyelve van, és mindegyik ugyanarra a CLR-re fordul:

NyelvStílusKi használja?
C#objektumorientált, C-szintaxisa .NET fő nyelve
F#funkcionálisadatelemzés, pénzügyi világ
VB.NETbeszédes, Basic-örökségrégebbi vállalati rendszerek

Mindhárom nyelv ugyanazt a BCL-t (Base Class Library — alaposztály-könyvtár) használja: a Console, a Math, a String, a List és társaik közösek. Amikor a tananyagban „beépített osztályt” mondunk (I blokk), mindig a BCL-ről beszélünk.

Kinek a dolga?

Döntsd el mindegyik feladatról: a C#-fordító, a JIT, a GC vagy a BCL végzi?

1 / 8Pontszám: 0

6És a Python? — összevetés azzal, amit már ismersz

PythonC# (.NET-en)
Hol fut?egy értelmezőn (sorról sorra)fordítás után a CLR-en
Fordításfutás közbenelőre IL-re, futáskor JIT
Hibák jelzésetipikusan futás közben derül kia fordító futtatás előtt sokat elkap
Típusokmenet közben változhatnakrögzítettek, a fordító őrzi
Memóriaautomatikus (GC)automatikus (GC) — ez közös!

A legnagyobb napi különbség a hibajelzés: C#-ban a program el sem indul, amíg a fordító hibát lát. Ez eleinte szigorúnak tűnik — valójában ajándék: a hibát te látod meg, nem a felhasználó.

7Gyakorlat — nézd meg az IL-t a saját szemeddel!

A sharplab.io oldalon C#-fordító fut a böngészőben: bal oldalra kódot írsz, jobb oldalon azonnal látod, mi készül belőle.

  1. Nyisd meg a sharplab.io-t. A jobb oldali panel tetején válts IL nézetre.
  2. Írd be bal oldalra:
int a = 5;
int b = 3;
System.Console.WriteLine(a + b);
  1. Figyeld meg a jobb oldalt: ez az IL. Nem kell értened — ezt a három dolgot keresd meg benne:
// … részlet a generált IL-ből:
ldc.i4.5      // betölti az 5-öt
ldc.i4.3      // betölti a 3-at
add           // összeadja őket
call void [System.Console]System.Console::WriteLine(int32)
  1. Változtasd az összeadást szorzásra (a * b) — figyeld, hogyan változik az IL (addmul).

8Feladatok

Gyakorló feladatok

⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás

A3.1

Rajzold le fejből az utat a Program.cs-től a processzorig. Hol van benne az IL, hol a JIT?

A3.2

Melyik betűszó mit takar: CLR, IL, JIT, GC, BCL? Írd le mindegyikhez egy mondatban a feladatát is.

A3.3⭐⭐

Egy munkatársad C++-ban programozik, és azt mondja: „a C# lassú, mert futás közben még fordítgat”. Mit válaszolnál? Említsd meg azt is, mit nyerünk cserébe. (Segítség: platformfüggetlenség, típusbiztonság, GC.)

A3.4⭐⭐

A sharplab.io-n írd be: System.Console.WriteLine("C#".Length); — mit ír ki a program (jobb oldalt válts Run nézetre)? Mit mond ez arról, hogy „minden objektum”? (Még egy string literálnak is van tulajdonsága!)

A3.5⭐⭐⭐

Nézz utána: a Java világában mi felel meg az IL-nek és a CLR-nek? (Keresőszavak: bytecode, JVM.) Miben hasonlít a két rendszer, és miben tér el?

9Önellenőrző kvíz

Ellenőrizd magad!

Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.

10Fogalomtár

FogalomJelentés
gépi kóda processzor saját utasításkészlete — csak ezt tudja végrehajtani
fordító (compiler)program, amely az egyik nyelvű kódból másik nyelvűt készít
IL (Intermediate Language)köztes nyelv: erre fordul a C#-forráskód
CLR (Common Language Runtime)a .NET futtatókörnyezete: betölti, JIT-eli, felügyeli a programot
JIT (Just-In-Time)futás közbeni fordítás IL-ből az adott gép gépi kódjára
GC (Garbage Collector)automatikus memória-felszabadítás: eltakarítja az elérhetetlen objektumokat
BCL (Base Class Library)a .NET beépített osztálykönyvtára (Console, Math, String, List…)
System.Objectminden .NET-típus közös őse — ezért „minden objektum”
runtime (futtatókörnyezet)az a szoftverréteg, amely a programot futtatja — .NET-programhoz .NET runtime kell

11Összegzés

  1. A C#-forráskód két lépésben jut a processzorig: a fordító IL-re fordítja, futáskor a CLR JIT-fordítója készít belőle gépi kódot.
  2. Az IL platformfüggetlen — ezért futhat ugyanaz a program Windowson, Linuxon és macOS-en, ahol van .NET runtime.
  3. A CLR a program „gondnoka”: JIT-el, memóriát kezel, típusokat őriz, kivételeket közvetít. A GC automatikusan felszabadítja az elérhetetlen objektumokat.
  4. Minden típus a System.Object leszármazottja — még az int-nek is vannak metódusai (ToString, GetType), mert az int a System.Int32 álneve.
  5. A .NET nyelvcsalád (C#, F#, VB.NET) közös CLR-en és közös BCL-en osztozik.
  6. A JavaScripthez képest a legnagyobb különbség: a C#-fordító a hibák nagy részét futtatás előtt megtalálja.