Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)

Hasonló előadás


Az előadások a következő témára: "Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)"— Előadás másolata:

1 Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) OE-NIK HP

2 Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) OE-NIK HP 2

3 Eseménykezelés PPT és VEP tananyag
A prezentációban eseményt kiváltó és eseményt feldolgozó osztályról beszélünk, de eseménykezelés lehetséges akár egyetlen osztályon belül is Cél: esemény bekövetkezésének jelzése más modul/osztály részére Módszerek: Függvénymutató átadása (DOS), Delegate-ek használata (C#), Interfészek használata (JAVA) Ezen az órán csak a C# megvalósítással foglalkozunk A módszereket el lehet magyarázni néhány mondatban OE-NIK HP 3

4 Delegate Egy típus, amelybe metódusokat tudunk „belerakni”
A deklarációnál meg kell kötni, hogy milyen szignatúrájú metódust tud tárolni az adott delegate: delegate double MyDelegate(int param1, string param2); Név: MyDelegate Visszatérési típus: double Paraméterek: 2 db, int+string Fontos: ez még csak egy típusdeklaráció  Változó nélkül nem használható Referenciatípus Metóduson belül nem deklarálható Osztályon belül és kívül is deklarálható Szignatúra: már tudniuk kéne, de biztos el kell magyarázni „típusdeklaráció”, mint a CLASS kulcsszó OE-NIK HP 4

5 Delegate használata delegate double MyDelegate(int param1, string param2); double funct(int elso, string masodik) { return elso + masodik.Length; } Más metóduson belül: MyDelegate del; del = new MyDelegate(funct); Console.WriteLine(del(5, "hello")); OE-NIK HP 5

6 Delegate használata delegate double MyDelegate(int param1, string param2); double funct(int elso, string masodik) { return elso + masodik.Length; } Osztály deklarációs részében (metódusokon kívül): MyDelegate del; Más metóduson belül: del += funct; Console.WriteLine(del(5, "hello")); Amíg nem rakunk a delegate-be metódust, az értéke NULL  hívás előtt ellenőrizni kell! Lehetséges több metódust belerakni egy delegate-be OE-NIK HP 6

7 Delegate-paraméter delegate bool Összehasonlító(object bal, object jobb); class EgyszerűCserésRendező { public static void Rendez(object[] Tömb, Összehasonlító nagyobb) for (int i = 0; i < Tömb.Length; i++) for (int j = i + 1; j < Tömb.Length; j++) if (nagyobb(Tömb[j], Tömb[i])) object ideiglenes = Tömb[i]; Tömb[i] = Tömb[j]; Tömb[j] = ideiglenes; } Elmondani: paraméterként minden olyan delegate-változót meg lehet adni, aminek a szignatúrája illeszkedik (sőt, akár magát a metódust delegate nélkül) a látható kód apró hiányossága, hogy a delegate-et NULL ellenőrzés nélkül hajtja végre – inicializálatlan delegate esetén ez nullreferenceexception-t jelent OE-NIK HP 7

8 Delegate-paraméter példaosztály
class diak { public string nev; public int kreditek; public diak(string ujnev, int ujkreditek) nev = ujnev; kreditek = ujkreditek; } public override string ToString() return nev + " - " + kreditek; diak[] csoport = new diak[] { new diak("Első Egon", 52), new diak("Második Miksa", 97), new diak("Harmadik Huba", 10), new diak("Negyedik Néró", 89), new diak("Ötödik Ödön", 69) }; OE-NIK HP

9 Delegate-paraméter kód
bool mycomp(object elso, object masodik) { return ((elso as diak).kreditek < (masodik as diak).kreditek); } Összehasonlító del = new Összehasonlító(mycomp); EgyszerűCserésRendező.Rendez(csoport, del); VAGY EgyszerűCserésRendező.Rendez(csoport, mycomp); OE-NIK HP

10 Eseménykezelés Eddig: tudunk egy osztályon belül delegate-et deklarálni, és használni Cél: osztályok közötti átjárhatóság  funkcionalitás szempontjából a delegate erre jó, a delegate típusnál csak a metódus szignatúrája számít, az azt tartalmazó osztály nem Gyakorlatilag az eseményt kiváltó osztályban egy publikus delegate típusú változó kell Az „event” kulcsszót használjuk annak jelzésére, hogy ez egy esemény lesz Szerepelhet interface-ben (sima delegate változó nem) Meghívni csak a tartalmazó osztályból lehet (sima publikus delegate-et bárhonnan) Kötött szignatúra: void visszatérési típus, Sender + EventArgs paraméter OE-NIK HP

11 Eseménykezelés Az eseményt lekezelő osztályból rakunk bele egy metódust az eseményt kiváltó osztály delegate-jébe (csak += és -= operátorok!) Vagyis, ha meghívjuk a delegate-et  a külső metódust hívjuk meg Fontos: Az eseményt kiváltó osztályban az esemény-delegate meghívásakor nem tudjuk, hogy a delegate tartalmaz-e metódust (vagyis: nem tudjuk, hogy rendeltek-e eseménykezelőt az eseményhez) Ezért a delegate meghívása előtt mindig figyelni kell a NULL értéket Lehetőség van egy eseményhez több eseménykezelőt is rendelni, bár ez a Visual Studio tervező nézetében nem megoldott OE-NIK HP 11

12 Eseménykezelés – Névkonvenciók
Feladat Név Elhelyezés Eseményparaméter ValamiEventArgs A névtérben vagy a kiváltó osztályban Delegate ValamiEventHandler A névtérben vagy a kiváltó osztályban Esemény Valami Kiváltó osztályban Eseményt közvetlenül meghívó metódus OnValami Esemény lekezelése --- Lekezelő osztályban ValamiEventArgs: opcionális. Mese: van olyan esemény, ahol elég az esemény maga (pl. Click, Connect), és ez elmondja, hogy valami történt. Van olyan esemény, ahol az esemény mellé extra információkat akarunk adni (pl. MouseClick, MouseMove). Erre való az eseményparaméter. Ha nem kell saját, akkor: EventArgs (amúgy is ez az ős) ValamiEventHandler: object sender + eventargs paraméterű, void visszatérési típusú OnValami: opcionális, általában akkor, ha az esemény több helyen is bekövetkezhet a kódban, és nem akarjuk a NULL-ellenőrzést ismételni, vagy az esemény-loggolást ismételni --- Ez a külön metódus CSAK az esemény meghívását végzi el Esemény lekezelése az eseményt lekezelő osztályban: automata elnevezést fogunk többnyire használni OE-NIK HP

13 Eseménykezelés feladat
Hozzunk létre Windows Forms alkalmazást, benne a korábban említett Diák {Név, Kreditek} osztállyal Legyen lehetőségünk diákok felvitelére, a felvitt diákok jelenjenek meg egy ListBox vezérlőben Az egyes diákoknak gomb segítségével tudjuk növelni a kreditszámát A diák osztályban következzen be a PrímaDiák esemény, ha a kreditszám-változás után a kreditek száma prímszám Az esemény küldője a kiváltó példány legyen, eseményparaméterként küldjük el az aktuális időt A Form osztályban iratkozzunk fel az eseményre, és a prím-diákokról vezessünk egy külön listát Mivel első alkalom, ezért ismételjük el az osztály-létrehozást: adattagok + tulajdonságok + konstruktor(ok) + ToString() + többi eljárás OE-NIK HP 13

14 Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) OE-NIK HP 14

15 Névtelen metódusok Angolul: anonymous methods Célok:
Kód lerövidítése, olvashatóbbá tétele Apró, „levegőben lógó” metódusok és eseménykezelők számának csökkentése A metódussal való paraméterezés megkönnyítése, rövidítése Ezáltal a létrehozott osztályok „általánosságának” növelése (az osztály működése is módosíthatóvá válik azáltal, hogy metódusokat adhatunk meg paraméterül) OE-NIK HP 15

16 Gyakori példa: dinamikus vezérlők létrehozásánál
for (int x = 0; x < 5; x++) { for (int y = 0; y < 5; y++) Button uj = new Button(); uj.Top = y * 50; uj.Left = x * 50; uj.Width = uj.Height = 40; uj.Text = x + ";" + y; Controls.Add(uj); uj.Click += new EventHandler(uj_Click); } // Cél: Mindegyik gombra fusson le egy eseménykezelő Elmondani: uj.Click += <TAB> <TAB> , és automatikusan megvan az eseménykezelő, egy külön metódus, amiben meg tudjuk írni az eseménykezelőnket OE-NIK HP

17 Eseménykezelő írásának problémái
Tipikusan: egy nagyobb programhoz több saját vezérlő, mindegyikben több saját osztály, több egyedi esemény van Probléma: Az események lekezelésekor minden eseménykezelő egy külön metódus, amik sokszor nagyon egyszerűek. Egy nagy programban rengeteg soros metódus kerül, ráadásul az eseménykezelő hozzárendelése (a += operátoros sor) és az eseménykezelő kódja távol kerül egymástól  külön deklarált metódusok helyett úgynevezett névtelen metódusokat használunk  „anonymous methods” Lényegük: a metódust nem deklaráljuk külön (ezért névtelen: nincs névvel deklarálva, csak kóddal), így egyszerűen megmondjuk, hogy „ha bekövetkezik az esemény, akkor tedd EZT” OE-NIK HP

18 Gyakori példa: dinamikus vezérlők létrehozásánál
Button uj = new Button(); uj.Top = y * 50; uj.Left = x * 50; uj.Width = uj.Height = 40; uj.Text = x + ";" + y; Controls.Add(uj); uj.Click += delegate { MessageBox.Show("CLICKED"); }; Záró pontosvessző !!! Elmondani: FIGYELNI KELL A ZÁRÓ PONTOSVESSZŐRE! Metódus-definíció után általában nincs pontosvessző, itt azért van, mert uj.Click+=valami; csak épp a valami az egy anonymous method OE-NIK HP

19 Gyakori példa: dinamikus vezérlők létrehozásánál
Button uj = new Button(); uj.Top = y * 50; uj.Left = x * 50; uj.Width = uj.Height = 40; uj.Text = x + ";" + y; Controls.Add(uj); uj.Click += delegate(object kuldo, EventArgs esemenypar) { MessageBox.Show((kuldo as Button).Text); }; Elmondani: ha paraméteres névtelen metódust adok hozzá, akkor a szignatúra illeszkedését ellenőrzi a fordító OE-NIK HP

20 Névtelen metódusok Előny: könnyebben olvasható kód (egyesek szerint  ) Csak az egyszer használatos, és lehetőleg rövid eseménykezelőt írjuk így meg: a hosszú kód olvashatatlan, és mivel „beágyazott kód”, ezért nem újrafelhasználható Lehetőleg ne ágyazzunk egymásba névtelen metódusokat Használatukkal lehetőség van leegyszerűsíteni a korábban delegate-paraméterek használatát is OE-NIK HP

21 Delegate-paraméter delegate bool Összehasonlító(object bal, object jobb); class EgyszerűCserésRendező { public static void Rendez(object[] Tömb, Összehasonlító nagyobb) for (int i = 0; i < Tömb.Length; i++) for (int j = i + 1; j < Tömb.Length; j++) if (nagyobb(Tömb[j], Tömb[i])) object ideiglenes = Tömb[i]; Tömb[i] = Tömb[j]; Tömb[j] = ideiglenes; } Elmondani: paraméterként minden olyan delegate-változót meg lehet adni, aminek a szignatúrája illeszkedik VAGY névtelen metódust is OE-NIK HP 21

22 Delegate-paraméter példaosztály
class diak { public string nev; public int kreditek; public diak(string ujnev, int ujkreditek) nev = ujnev; kreditek = ujkreditek; } public override string ToString() return nev + " - " + kreditek; diak[] csoport = new diak[] { new diak("Első Egon", 52), new diak("Második Miksa", 95), new diak("Harmadik Huba", 10), new diak("Negyedik Néró", 84), new diak("Ötödik Ödön", 69) }; OE-NIK HP

23 Delegate-paraméter példa
EgyszerűCserésRendező.Rendez(csoport, delegate(object elso, object masodik) { return (elso as diak).nev. CompareTo((masodik as diak).nev) < 0; }); return (elso as diak).kreditek < (masodik as diak).kreditek; OE-NIK HP

24 Anonymous függvények feladat
Hozzunk létre Windows Forms alkalmazást, benne a korábban említett Diák {Név, Kreditek} osztállyal Legyen lehetőségünk diákok felvitelére, a felvitt diákok jelenjenek meg egy ListBox vezérlőben Az egyes diákoknak gomb segítségével tudjuk növelni a kreditszámát A diák osztályban következzen be a Prim esemény, ha a kreditszám-változás után a kreditek száma prímszám Az esemény küldője a kiváltó példány legyen, eseményparaméterként küldjük el az aktuális időt A Form osztályban iratkozzunk fel az eseményre, és a prím-diákokról vezessünk egy külön listát A fenti eseménykezelőt írjuk át névtelen metódussá OE-NIK HP 24

25 Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) OE-NIK HP 25

26 Források Events tutorial: Event modifier: Anonymous methods: Anonymous methods: Anonymous methods: Anonymous methods: Delegate, Anonymous, Event: Reiter István: C# jegyzet ( , oldal OE-NIK HP

27 OE-NIK HP

28 OE-NIK HP


Letölteni ppt "Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)"

Hasonló előadás


Google Hirdetések