Začíname novú a dosť významnú kapitolu o programovaní udalostne orientovaných programov. Uvidíte, že to nie je nič zložité a určite nájdete veľa dobrých nápadov ako využiť udalosti vo svojich programoch. Veľmi vhodný článok aj pre programátorov prechádzajúcich z C++ na C#. Článok nie je obmedzený verziou .NET.
Možno, že ste sa ešte nestretli s pojmom “udalostne orientované programy“, ale tým, že čítate tento text už využívate taký program :-). Najjednoduchším príkladom sú klasické oknové programy vo Windows (alebo inom OS, ktorý používa technológiu šírenie udalostí).
Udalosť vzniká, keď pohnete myšou, keď stlačíte tlačítko alebo keď stlačíte klávesu. Keď nejaká udalosť vznikne, operačný systém (napr. Windows) predá jej šírenie všetkým programom, ktoré dokážu na takýto typ udalosti reagovať.
Obsluha udalosti je jednoduché zavolanie klasickej funkcie (metódy), (ktorú programátor naprogramoval) a dokáže urobiť nejakú činnosť, ktorá prislúcha danej udalosti. Udalosti sú základom interaktívnych programov.
Programátori v C++ sa s takouto technológiou nestretli. Možno, že teraz hovoríte, čo za bludy to tu píšem, veď Vy bežne programujete oknové programy a všetko to fachčí :-) aj v C++. Hneď dám všetko na pravú mieru. Udalosti v C++ sú implementované len pomocou nejakých knižníc, ktoré sú najčastejšie proprietárne (vytvorené firmou, ale natoľko používané, že sú takmer štandardné) . Napr. je to MFC používané vo Visual C++ alebo aj firma Borland má na udalosti vlastnú knižnicu, alebo si môžete takú knižnicu spraviť sami použitím pointrov na funkcie. A všetky tieto knižnice sa zas opierajú o knižnice WinAPI.
Hlavný rozdiel medzi C++ a C#, čo sa týka udalostí je v tom, že udalosti v C# fungujú už na úrovni syntaxe a nie sú potrebné ďalšie knižnice (čo je super :-))
Udalosti sa používajú vo všeobecnosti vtedy, keď programátor nejakej funkcie vopred nevie, kto všetko a odkiaľ ju bude volať (spúšťať).
Napr. programátor triedy jednoduchého tlačítka naprogramuje udalosť, ktorá znamená, že sa na tlačítko kliklo. A vy ako druhý programátor, naprogramujete funkciu - obsluhu udalosti, ktorá sa má vykonať, keď sa táto udalosť vyvolá.
Jednoduchý príklad :-)
Často sa udalosti vysvetľujú aj na architektúre Vydavateľ/Odberateľ napr. novín, tých papierových :-). Vydavateľstvo nevydáva a neposiela noviny konkrétne iba Vám (to predstavuje klasický princíp volania funkcií), ale umožňuje odberateľom zaregistrovať sa a ako náhle sa objaví nový výtlačok ( udalosť v tomto prípade je samotné vytlačenie nového výtlačku) rozpošle ho všetkým zaregistrovaným odberateľom.
Tu je si dobré všimnúť, že na jednu udalosť môže zareagovať aj viacero iných funkcií.
Ak si ešte stále nie ste istí, či ste udalosti správne pochopili, napíšte bez ostychu dole do diskusie alebo na môj e-mail.
>>Udalosti pekne od podlahy.
Skôr ako začneme pracovať s udalosťami musíme si vysvetliť možno pre Vás nový dátový typ - delegate (delegát).
Delegáta a delegovanie veľmi rady využívajú šéfovia vo firmách. Šéf dokáže vykonávať nejaké funkcie. Je potrebné, aby vycestoval, ale nechce sa mu (pardon, je časovo zaneprázdnený :-) ), tak poverí – deleguje nejakou svojou funkciou svojho
zamestnanca – delegáta a pošle na pracovnú cestu jeho, aby ho zastúpil.
To isté robí aj delegate v C#. Je to typ premennej, ktorá dokáže zastúpiť určitú funkciu (na ktorú je prepravená) ľubovoľnej triedy. Najčastejšie sa delegáti používajú ako parametre iných funkcií a na tvorbu udalostí (asi už tušíte prečo).
>>Vytvorenie delegáta
Ak viete programovať aj v C/C++, tak už asi tušíte, že delegáti sú si veľmi podobní s pointrom (ukazovateľom) na funkciu. Rozdiel je v tom, že delegáti dokážu zastúpiť aj metódy tried, čo v C++ nebolo možné. Ale to len na okraj.
Základom, čo si musíte uvedomiť je, že delegát je trieda alebo dátový typ (ako int alebo string), zjednodušene povedané. Takže predtým ako ho budeme používať musíme
1. ) vytvoriť nový typ delegáta, podľa toho, aký typ funkcií, chceme aby dokázal zastúpiť
2.) zadeklarovať premennú podľa nami vytvoreného typu delegáta
3. ) naplniť hodnotou = new + odkaz na metódu, funkciu triedy, ktorú má zastúpiť.
Veď mrknite na príklad a uvidíte.
Príklad 12.1