Pomocou delegátov môžete používať metódy ako klasické objekty a vďaka tomu ich predávať iným triedam. Udalosti túto funkčnosť rozširujú a používajú sa na spustenie metód pri určitých udalostiach.
Delegáti sú zaujímavá časť jazyka C# dovoľujúca priradiť metódy k premenným a používať ich ako objekty. To nám dovoľuje priradiť metódu napísanú v jednej funkcií funkcií inej, ktorá je na to pripravená.
Deklarácia delegáta
Deklarácia delegáta je odlišná od deklarácie klasických premenných alebo funkcií, jeho definícia je spojenie oboch. Začnete podobne ako pri deklarácií premennej s tým, že ako posledný modifikátor použijete delegate, čím označíte že sa bude jednať o delegát. Deklarácia však nekončí menom premennej, ale parametrami, ktoré budú mať priraďované metódy.
public delegate float SpravNiecoSCislom(float vstup);
V tejto premennej sme deklarovali delegát funkcie, ktorá bude mať návratový typ a parameter typu float. Tento delegát následne môžete zavolať s funkcie vnútri triedy kde bol definovaný.
public class UkazkovaTrieda { public delegate float SpravNiecoSCislom(float vstup); public void Metoda(float vstup) { Console.WriteLine(SpravNiecoSCislom(vstup)); } }
Tu sme v metóde triedy UkazovaTrieda zavolali náš delegát. Aby toto však fungovalo je nutné mu priradiť nejakú hodnotu.
Priradenie metódy k delegátovi
Pokiaľ chcete delegátovi priradiť metódu, musíte ju napísať, zároveň musí delegátovi odpovedať v jeho návratovom type a parametroch.
public float DruhaMocnina(float vstup) { return vstup*vstup; }
Táto metóda, ktorá vráti druhú mocninu vstupného parametru nášmu delegátovi odpovedá, je ju teda možné priradiť.
UkazkovaTrieda trieda = new UkazkovaTrieda(); trieda.SpravNiecoSCislom = DruhaMocnina; trieda.Metoda();
V tomto kóde sme vytvorili objekt typu UkazkovaTrieda a jeho delegátovi SpravNiecoSCislom sme priradili našu metódu. Tento delegát bude v metóde Metoda zavolaný a vykoná práve našu funkciu. Týmto spôsobom môžeme vytvoriť dva objekty jednej triedy, ktoré budú mať ako jeden delegát dve rôzne metódy, alebo vymieňať metódy delegáta za behu.
Vytvorenie udalostí
Udalosti sú druhom delegátov využívanom po splnení určitých podmienok, napríklad po stlačení tlačidla alebo zmene premennej. Veľa tried v C# (hlavne spojených s grafickým rozhraním) používa udalosti. Ako však udalosť vytvoríte? Je to podobné ako s delegátom, len neurčujete parametre a výstupný typ.
public event EventHandler Udalost;
Na deklaráciu udalosti použijete kľúčové slov event a výstupný typ EventHandler. Zavolanie udalosti je podobné ako by to bol delegát, zaujímave sú však parametre. Prvý parameter udalosti je vždy typu object a malo by sa jednať o triedu, v ktorej bola daná udalosť zavolaná. O type object sme si ešte nepovedali, pričom je to najzákladnejší dátový typ v jazyku C# – jedná sa o typ, ku ktorému je následne možné priradiť čokoľvek.
object nieco = 3; nieco = "Text"; nieco = new Trieda(); nieco = new int[]{3, 2, 8};
V tomto kóde sme vytvorili objekt nieco, do ktorého sme priradili číslo 3 (int), následne string „Text“, objekt triedy a pole. Predošlá hodnota je samozrejme po priradení vždy stratená, tento príklad mal však ukázať že do objektu je možné priradiť akýkoľvek dátový typ.
Vráťme sa však k volaniu udalosti. Prvý parameter sme si už povedali, druhý parameter je typu EventArgs, čiže obsahuje argumenty udalosti. Vo väčšine prípadov používate triedy odvodené od tohto typu aby ste mohli informovať metódu udalosti o tom, čo sa vlastne stalo. Pri stlačení klávesy napríklad aký kláves bol stlačený.
Udalost(this, new KeyEventArgs(klaves));
Tu sme zavolali našu udalosť s vstupným parametrom odosielateľa (našej triedy) a argumentov typu KeyEventArgs obsahujúcich vstupnú premennú klaves.
Pri deklarácií udalosti môžete definovať vlastný druhý parameter nasledujúcim spôsobom :
public event EventHandler<KeyEventArgs> Udalost;
Po tomto je možné udalosti priradiť len parameter typu KeyEventArgs a od neho odvodený a nie akéhokoľvek typu odvodeného do EventArgs.
Priradenie udalosti
K udalosti je nutné priradiť metódu – to je oproti delegátom mierne odlišné. Na začiatok si však túto metódu napíšeme.
public void KlavesStalceny(object sender, EventArgs e) { KeyEventArgs key = (keyEventArgs)e; Console.WriteLine(key.klaves.ToString()); }
Táto metóda spĺňa typy parametrov vytvorenej udalosti – tým že sme nešpecifikovali typ jej druhého parametru, musíme použiť typ EventArgs. Ten následne v kóde pretypujeme na pre nás vhodný typ. Mená vstupných parametrov sender a e sú štandardnými menami parametrov pre udalosti, môžete však použiť akékoľvek mená, aké chcete.
Pokiaľ budete chcieť túto metódu priradiť udalosti, použijete kód podobný ako pri delegátoch.
trieda.Udalost += KlavesStlaceny;
Ako vidíte, pri priradení použijete operátor += namiesto klasického =. Tým je zabezpečené, že jedna udalosť môže zavolať viacej metód z rôznych tried. To nieje často používané, prakticky to použijete len pokiaľ je udalosť vytvorená v statickej triede. Podobným spôsobom (pomocou -=) môžete od udalosti metódy aj odoberať.
Na konci tohto dielu si len povieme, že udalosti sú veľmi užitočné, ale pokiaľ sú používané vo veľkom množstve, môžu spomaliť výkon programu. V ďalšom, poslednom klasickom diely sa pozrieme na Vlákna a ich funkčnosť.