1. diel - Úvod do C# a .NET Frameworku
Vitajte pri prvej lekcii populárneho C# .NET kurzu, ktorý vám odhalí jazyk C# aj framework .NET. Budeme sa učiť postupne, od úplných začiatkov až po zložité konštrukcie, objektové modely a napr. prácu s databázou alebo webové aplikácie. S trochou trpezlivosti a vytrvalosti sa tak z teba stane dobrý programátor.
Aby sme plne porozumeli jazyku C#, obzrime sa do minulosti na to, ako sa programovacie jazyky vyvíjali. Bude pre nás dôležité pochopiť, ako C# pracuje a prečo je dobré programovať práve v ňom.
Vývoj programovacích jazykov
1. generácia jazykov – Strojový kód
Procesor počítača vie vykonávať len obmedzené množstvo jednoduchých inštrukcií, ktoré sú uložené ako sekvencie bitov, sú to teda čísla. Tie sa mu obvykle zadávajú v hexadecimálnej (šestnástkovej) sústave. Inštrukcie sú tak elementárne, že umožňujú iba napr. sčítanie adries alebo skoky medzi inštrukciami. Nie je možné napr. jednoducho sčítať dve čísla, musíme sa na čísla pozerať ako na adresy v pamäti a také sčítanie čísel zaberie niekoľko inštrukcií. Program sčítajúci dve čísla by vyzeral napr. takto:
2104 1105 3106 7001 0053 FFFE 0000
Inštrukcie sa procesoru predložia v binárnej podobe. Takýto kód je samozrejme extrémne nečitateľný a závisí od inštrukčnej sady daného CPU. V tomto jazyku určite nebude jednoduché tvoriť nejaké programy, žiaľ každý program musí byť nakoniec do tohto jazyka preložený, aby mohol byť na procesore počítača spustený:
2. generácia jazykov – Assembler
Assembler (skrátene ASM) nie je o nič jednoduchšie ako strojový kód, ale je ľudsky čitateľný. Ide o strojový kód, v ktorom majú inštrukcie slovné označenie (kód), človek si teda nemusí pamätať čísla. Kódy inštrukcií sa potom preložia do vyššie uvedeného strojového kódu. Rovnaký program by v ASM vyzeral takto:
ORG 100 LDA A ADD B STA C HLT DEC 83 DEC –2 DEC 0 END
Vidíme, že podoba je trochu ľudskejšia, ale nezasvätení ľudia stále vôbec netušia, ako program funguje (vrátane mňa).
3. generácia jazykov
Jazyky v tretej generácii konečne ponúkajú užívateľovi určitú abstrakciu toho, ako program vidí počítač, a zameriavajú sa na to, ako program vidí človek. Naše čísla sú vnímané už ako premenné, zdrojový kód pripomína matematický zápis.
Sčítanie dvoch čísel by v jazyku C vyzeralo takto:
int main(void) { int a, b, c; a = 83; b = -2; c = a + b; return 0; }
Všetci asi tušíme, čo program robí: spočíta čísla 83
a
-2
a výsledok uloží do premennej c
. Pri všetkých
jazykoch tretej generácie je samozrejme výhodou vysoká čitateľnosť. S
ďalším vývojom išli jazyky ešte ďalej a priniesli objektovo orientované programovanie, ale o tom až
neskôr. Jazyky v tretej generácii spadajú v zásade do troch kategórií:
1. Kompilované jazyky
Kompilované (neriadené) jazyky majú teda svoj zdrojový kód v jazyku, ktorému ľudia dobre rozumejú. Tento zdrojový kód sa samozrejme musí preložiť do strojového kódu, aby ho bolo možné spustiť na procesore. Tento preklad zaisťuje prekladač (kompiler), ktorý preloží naraz celý program do strojového kódu:
Kompilácia má tieto výhody:
- Rýchlosť – Jediné zabrzdenie spočíva v jednorazovej kompilácii, preložený program potom beží porovnateľne rýchlo, ako keby bol napísaný napr. v ASM.
- Neprístupnosť zdrojového kódu – Program sa šíri už skompilovaný, nie je ho teda možné jednoducho modifikovať, pokiaľ zároveň nevlastníte jeho zdrojový kód.
- Jednoduché odhalenie chýb vo zdrojovom kódu – Ak zdrojový kód obsahuje chybu, celý proces kompilácie spadne a programátor je s chybou oboznámený. To značne zjednodušuje vývoj.
Ďalej sú tu samozrejme aj nevýhody:
- Závislosť na platforme – Program je stále závislý na platforme, teda na type procesora a operačnom systéme. Skompilovaný program nemôžeme vziať a preniesť na inú platformu bez toho, aby bol na tejto platforme znova skompilovaný.
- Nemožnosť editácie – Akonáhle sa program raz skompiluje do strojového kódu, nemožno ho editovať inak ako opätovnou kompiláciou. To pochopiteľne platí aj pre vyššie spomínané jazyky.
- Memory management – Vzhľadom na to, že počítač danému programu nerozumie a len mechanicky vykonáva inštrukcie, môžeme sa niekedy stretnúť s veľmi nepríjemnými chybami s pretečením pamäte. Kompilované jazyky zvyčajne nemajú automatickú správu pamäte a sú to jazyky nižšie (s nižším komfortom pre programátora). Behové chyby spôsobené najmä zlou správou pamäte sa kompiláciou neodhalia.
Príkladom kompilovaných jazykov sú napr. jazyk C, jeho objektový následník C++ alebo Pascal / Delphi.
2. Interpretované jazyky
Interpretácia sa snaží riešiť problém prenositeľnosti programov medzi rôznymi platformami a taktiež prichádza s vyšším komfortom pre programátora. Interpret funguje podobne ako kompiler, len neprekladá program celý naraz, ale iba to, čo je v danej chvíli potrebné. (Interpreter znamená v angličtine tlmočník, najskôr teda vypočuje jednu vetu hovorcu a tú potom preloží a vysloví. Preklad prebieha počas príhovoru, teda behu programu, po vetách/inštrukciách. Kompiler/prekladač preloží rozhovor celý naraz a potom ho celý prečíta.) Môžeme si predstaviť, že vyššie uvedený zdrojový kód by interpret čítal po jednotlivých riadkoch, tú časť by vždy skompiloval do strojového kódu a vykonal. Výsledok kompilácie by zahodil a presunul by sa na ďalší riadok. Možno vám to pripadá ako plytvanie výkonom procesora a je pravda, že tento spôsob behu programu tiež nie je práve najrýchlejší:
Aké môže mať teda tento postup výhody? Je ich hneď niekoľko:
- Prenositeľnosť – Program je plne prenositeľný, ak teda existuje interpret pre danú platformu, pôjde na nej zdrojový kód programu spustiť (a vývoj interpretu je jednoduchší ako vývoj kompilátora).
- Jednoduchší vývoj – Vo vyšších jazykoch sme odtienení od správy pamäte, ktorú za nás robí tzv. garbage collector (ďalej v seriáli si o ňom povieme viac). Často tiež nemusíme ani zadávať dátové typy a máme k dispozícii vysoko komfortné kolekcie a ďalšie štruktúry.
- Stabilita – Vďaka tomu, že interpret kódu rozumie, predíde chybám, ktoré by skompilovaný program inak pokojne vykonal. Beh interpretovaných programov je teda určite bezpečnejší. Ďalej umožňuje zaujímavú vlastnosť, tzv. reflexiu, kedy program za behu skúma sám seba, ale o tom neskôr.
- Jednoduchá editácia – Program môžeme vyvíjať po častiach a nahrávať na cieľové umiestnenie. Vďaka tomu, že sa nemusí kompilovať, ho je možné jednoducho editovať "za behu".
Interpret má tri zásadné nevýhody:
- Rýchlosť – Interpretácia môže byť často veľmi pomalá a program tak plne nevyužíva výkon počítača.
- Často ťažké hľadanie chýb – Kvôli kompilácii za behu sa chyby v kóde objavia až vo chvíli, keď je kód spustený. To môže byť niekedy veľmi nepríjemné.
- Zraniteľnosť – Pretože sa program šíri v podobe zdrojového kódu, každý do neho môže zasahovať alebo kradnúť jeho časti.
Príkladom interpretovaného jazyka je napr. PHP. Na väčšine webov tento pomerne pohodlný jazyk výkonovo stačí, ale napríklad Facebook používa špeciálnu kompilovanú verziu PHP, záujemcovia sa môžu pozrieť na projekt HipHop for PHP.
3. Jazyky s virtuálnym strojom
Napadlo vás, čo by sa stalo, keby sa oba dva vyššie spomenuté spôsoby spojili? Ak áno, gratulujem, vynašli ste virtuálny stroj. Ide o najmodernejšiu podobu jazyka, ktorá je v súčasnej dobe tiež najrozšírenejšou a najlepšou voľbou pre vývoj väčšiny aplikácií. Nebudem vám tajiť, že do tejto kategórie patrí samotný C# alebo Java.
Zdrojový kód je najskôr preložený do tzv. medzikódu, ktorému Microsoft hovorí CIL (Common Intermediate Language). Ide v podstate o strojový (binárny) kód, ktorý má ale o poznanie jednoduchšiu inštrukčnú sadu a priamo podporuje objektové programovanie. Tento medzikód je potom vďaka jednoduchosti relatívne rýchlo interpretovateľný tzv. virtuálnym strojom (teda interpretom, v prípade .NET je to tzv. CLR – Common Language Runtime). Výsledkom je strojový kód pre náš procesor:
Určite ste trochu vydesení, ale verte, že sme v podstate odstránili nevýhody interpretu i kompilera a môžeme využívať mnohé z ich výhod:
- Odhalenie chýb v zdrojovom kóde – Vďaka kompilácii do CIL jednoducho odhalíme chyby v zdrojovom kóde.
- Stabilita – Vďaka tomu, že interpret kódu rozumie, zastaví nás pred vykonaním nebezpečnej operácie a na chybu upozorní. Môžeme tiež vykonávať reflexiu (aj keď pre CIL, ale od toho sme väčšinou odtienení).
- Jednoduchý vývoj – Máme k dispozícii hi-tech dátové štruktúry a knižnice, správu pamäte za nás vykonáva garbage collector.
- Slušná rýchlosť – Rýchlosť sa pri virtuálnom stroji pohybuje medzi interpretom a kompilerom. Virtuálny stroj už výsledky svojej práce po použití nezahadzuje, ale dokáže ich cachovať, sám sa teda optimalizuje pri početnejších výpočtoch a môže dosahovať až rýchlosť kompilera (Just-In-Time Compiler). Štart programu býva pomalší, pretože stroj prekladá spoločne využívané knižnice.
- Málo zraniteľný kód – Aplikácia sa šíri ako zdrojový kód v CIL, nie je teda úplne jednoducho ľudsky čitateľná.
- Prenositeľnosť - Je zrejme jasné, že hotový program pobeží na každom železe, na ktorom sa nachádza virtuálny stroj. To ale nie je všetko, my sme dokonca nezávislí aj na samotnom jazyku. Na jednom projekte môže robiť viac ľudí, jeden napr. v C#, druhý vo Visual Basic a tretí v C++. Zdrojové kódy sa potom vždy preložia do CIL.
Jazyky s virtuálnym strojom ctia objektovo orientované programovanie a jedná sa o súčasný vrchol vývoja v tejto oblasti. Existujú aj jazyky 4. a 5. generácie, ale tie majú špecifické použitie a tu sa nimi zatiaľ nebudeme zaoberať.
.NET
Ako funguje C#, sme si teda vysvetlili, ešte si povedzme, čo presne je .NET. Rozumie sa ním v zásade štyri veci: jazyk, Visual Studio, virtuálny stroj (CLR) a knižnice.
Jazyk
Ako sme sa už zmienili, v .NET máme k dispozícii niekoľko jazykov, v ktorých môžeme vyvíjať. C# je z nich najmodernejší a bol prispôsobený práve pre .NET.
Visual Studio
Visual Studio je IDE (Integrated Development Environment), teda prostredie, v ktorom píšeme zdrojový kód a ktoré nám taktiež pomáha s vývojom. VS je veľmi uznávané aj v radoch javistov, jedná sa o moderné IDE, ktoré je vo verzii Community poskytované zadarmo, a to aj na komerčné účely.
Virtuálny stroj
CLR je virtuálny stroj, ktorý interpretuje CIL do inštrukcií fyzického procesora.
Knižnice
Knižnice sú asi najväčšou výhodou .NET. Microsoft nám v podstate dodáva kompletnú sadu knižníc, v ktorej máme predpripravený rad štruktúr a komponentov, napr. pre prácu s konzolou, databázami, formulárovými prvkami a podobne. Riešenia sú kvalitné a aktuálne, sú zdieľané medzi jednotlivými jazykmi. Keďže MS je autorom aj Windows, ich komponenty pekne pasujú a sú pre ich systém odladené. Pre beh aplikácií je potom nutné, aby na koncovej stanici bola tá istá verzia .NET, v ktorej bola aplikácia vyvinutá. Dobrá správa je, že Windows vždy majú nejaký .NET v sebe.
Implementácia .NET
.NET existuje v niekoľkých implementáciách (vydaniach). Poďme si ich tiež aspoň rýchlo predstaviť.
.NET Framework
Jedná sa o najstaršiu implementáciu .NET, ktorá už nie je aktívne vyvíjaná. Jej najnovšie verzie sú však stále podporované. Táto implementácia beží iba na systéme Windows.
.NET Framework má nasledujúcu štruktúru:
V .NET Frameworku 2.0 vidíme samotný CLR (virtuálny stroj) a základnú knižnicu Base Class Library. Verzia 3.0 prináša určité nové smery vo vývoji formulárových aplikácií a procesov. Zaujímavá pre nás bude najmä verzia 3.5, ktorá priniesla tzv. dotazovací jazyk LINQ, o ktorom si povieme viac neskôr. Ďalšia verzia umožňuje efektívne prevádzkovať LINQ na viacjadrových procesoroch. V roku 2012 potom ešte pribudla verzia 4.5, tá napr. zjednodušuje písanie asynchrónnych funkcií (o tom neskôr).
.NET Core (.NET)
.NET Core je novšia aktívne vyvíjaná open-source implementácia, ktorá je náhradou za staršiu .NET Framework.
Od verzie 5.0 sa z názvu vypustilo slovo "Core", máme teda napríklad .NET 5.0 alebo .NET 6.0.
Na rozdiel od .NET Frameworku nie je táto implementácia viazaná len na OS Windows, ale je pomocou nej možné vyvíjať aplikácie aj pre iné systémy, ako je napríklad Linux a od verzie 6.0 aj Android alebo iOS. Ďalšou jej významnou vlastnosťou je, že nemusí byť nainštalovaná na hosťujúcom zariadení:
Mono
Mono vzniklo ako podpora .NET na Linuxe, v tomto smere bolo však vytlačené novším .NET Core, do ktorého boli niektoré prvky Mona implementované. Práve vďaka Monu je možné v .NET vyvíjať aj pre iné systémy ako len Windows. Mono používa aj herný engine Unity, pretože podporuje aj herné konzoly.
Teraz Mono vyvíja spoločnosť Xamarin (vo vlastníctve Microsoftu).
.NET Standard
Aby bola zaistená určitá miera prenositeľnosti kódu medzi rôznymi implementáciami .NET, vznikol .NET Standard. Ide v podstate o špecifikáciu, ktorá určuje spoločnú funkcionalitu, ktorú každá implementácia .NET obsahuje.
Teraz vieme, s čím to vlastne budeme pracovať.
V budúcej lekcii, Visual Studio a prvá konzolová aplikácia v C# .NET, si ukážeme prácu s Visual Studiom a vytvoríme si svoj prvý program.