280 likes | 404 Views
Haladó Programozás. 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 ). PPT és VEP tananyag
E N D
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymousmethods) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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 Eseménykezelés Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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:delegatedoubleMyDelegate(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ó Delegate Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
delegatedoubleMyDelegate(int param1, string param2); doublefunct(intelso, stringmasodik) { returnelso + masodik.Length;} Más metóduson belül:MyDelegate del;del = newMyDelegate(funct);Console.WriteLine(del(5, "hello")); Delegate használata Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
delegatedoubleMyDelegate(int param1, string param2); doublefunct(intelso, stringmasodik) { returnelso + 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 Delegate használata Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
delegateboolÖsszehasonlító(object bal, object jobb); classEgyszerűCserésRendező { publicstaticvoid 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; } } } Delegate-paraméter Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Delegate-paraméter példaosztály classdiak { publicstring nev; publicint kreditek; public diak(string ujnev, int ujkreditek) { nev = ujnev; kreditek = ujkreditek; } publicoverridestring ToString() { return nev + " - " + kreditek; } } diak[] csoport = newdiak[] { newdiak("Első Egon", 52), newdiak("Második Miksa", 97), newdiak("Harmadik Huba", 10), newdiak("Negyedik Néró", 89), newdiak("Ötödik Ödön", 69) }; Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Delegate-paraméter kód bool mycomp(object elso, object masodik) { return ((elso asdiak).kreditek < (masodik asdiak).kreditek); } Összehasonlító del = newÖsszehasonlító(mycomp); EgyszerűCserésRendező.Rendez(csoport, del); VAGY EgyszerűCserésRendező.Rendez(csoport, mycomp); Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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 Eseménykezelés Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Eseménykezelés – Névkonvenciók Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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 Eseménykezelés feladat Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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) Névtelen metódusok Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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++) { Buttonuj = newButton(); uj.Top = y * 50; uj.Left = x * 50; uj.Width = uj.Height = 40; uj.Text = x + ";" + y; Controls.Add(uj); uj.Click += newEventHandler(uj_Click); } } // Cél: Mindegyik gombra fusson le egy eseménykezelő Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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 1-2-3 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” Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Gyakori példa: dinamikus vezérlők létrehozásánál Button uj = newButton(); 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ő !!! Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Gyakori példa: dinamikus vezérlők létrehozásánál Button uj = newButton(); 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 asButton).Text); }; Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
delegateboolÖsszehasonlító(object bal, object jobb); classEgyszerűCserésRendező { publicstaticvoid 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; } } } Delegate-paraméter Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Delegate-paraméter példaosztály classdiak { publicstring nev; publicint kreditek; public diak(string ujnev, int ujkreditek) { nev = ujnev; kreditek = ujkreditek; } publicoverridestring ToString() { return nev + " - " + kreditek; } } diak[] csoport = newdiak[] { newdiak("Első Egon", 52), newdiak("Második Miksa", 95), newdiak("Harmadik Huba", 10), newdiak("Negyedik Néró", 84), newdiak("Ötödik Ödön", 69) }; Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Delegate-paraméter példa EgyszerűCserésRendező.Rendez(csoport, delegate(object elso, object masodik) { return (elso asdiak).nev. CompareTo((masodik asdiak).nev) < 0; }); EgyszerűCserésRendező.Rendez(csoport, delegate(object elso, object masodik) { return (elso asdiak).kreditek < (masodik asdiak).kreditek; }); Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
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á Anonymous függvények feladat Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods) Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Források • Events tutorial: http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx • Event modifier: http://msdn.microsoft.com/en-us/library/8627sbea(vs.71).aspx • Anonymous methods: http://msdn.microsoft.com/en-us/magazine/cc163970.aspx • Anonymous methods: http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx • Anonymous methods: http://www.csharp-station.com/Tutorials/Lesson21.aspx • Anonymous methods: http://stackoverflow.com/questions/1116678/c-delegate-definition-anonymous-methods-vs-formally-defined-methods • Delegate, Anonymous, Event: Reiter István: C# jegyzet (http://devportal.hu/content/CSharpjegyzet.aspx) , 164-172. oldal Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu
Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu