Krizsán Zoltán
Események kezelése Nem kell vizuális felületnek letnek lennie. segíts tségével valósíthatja meg a.net. 2
Típusos fv.. pointer Biztonságos kódkk dkészítés s miatt tiltott a pointer aritmetika a. Fv.. Pointer helyett delegátum Alakja: delegate típus nev(tipus param_nev,..) Ha megadjuk a paraméter típust pusát, akkor a paraméter nevét t is meg kell adni! 3
Delegátum II. Nem csak a fv.. címe, c de visszatérési si érték k + paraméterek Amire hivatkozik, lehet: Statikus fv. Példány fv. 4
Példa delegate void MyDelegate(); public class MyClass{ public void InstanceMethod(){Console.WriteLine("A message from the instance method."); static public void StaticMethod(){Console.WriteLine("A message from the static method."); public class MainClass{ static public void Main(){ MyClass p = new MyClass(); MyDelegate d = new MyDelegate( p.instancemethod ); d(); d = new MyDelegate( MyClass.StaticMethod ); d(); 5
Részlet a Példa P il kódjából.class private auto ansi sealed MyDelegate extends [mscorlib]system.multicastdelegate{.method public hidebysig specialname rtspecialname instance void.ctor( object 'object', native int 'method' method ) runtime managed { // end of method MyDelegate::.ctor.method public hidebysig virtual instance void Invoke() runtime managed { // end of method MyDelegate::Invoke.method public hidebysig newslot virtual instance class [mscorlib]system.iasyncresult BeginInvoke(class [mscorlib]system.asynccallback callback, object 'object') runtime managed { // end of method MyDelegate::BeginInvoke.method public hidebysig newslot virtual instance void EndInvoke(class [mscorlib]system.iasyncresult result) runtime managed { // end of method MyDelegate::EndInvoke // end of class MyDelegate 6
MulticastDelegate minden delegátum őse _target (System.Object): az objektumra referál, amely a call back fv.-hez kapcsolódik (csak példány fv.. esetén). _methodptr (System.Int32): egész szám, amellyel a CLR azonosítja a fv.-t. _prev (System.MulticastDelegate): a láncolt l lista előző elemére mutat. 7
MulticastDelegate II. Két t fontos tulajdonság: Target->_target Method->_methodPtr Az Invoke fv.. nem hívhath vható meg közvetlenül l (VB-ben viszont kötelező). Equals újradefiniált, igaz, ha _target_ és s _methodptr_ azonosakra referál. 8
Delegátum lánc A delegátum önmagában is hasznos, de láncolt l listára fűzve f hatékonyabb _prev az előző elemre. Kezdetben null, később áll be egy érvényes objektumra. 9
System.Delegate public static Delegate Combine(Delegate tail, Delegate head) : hozzáfűz z a listához public static Delegate Combine(Delegate[] delegatearray) : hozzáfűz z a listához public static Delegate Remove(Delegate source, Delegate value) : töröl t l a listából 10
System.Delegate public static Delegate Combine helyett operator+= public static Delegate Remove helyett operator-= 11
Példa II.-set osztály class Set { private Object[] items; public Set(Int32 numitems){ items = new Object[numItems]; for (Int32 i =0; i < numitems; ; i++) items[i] ] = i; public delegate void Feedback(Object value,, Int32 item,, Int32 numitem); public void ProcessItems( Feedback feedback ){ for(int32 item = 0; item< items.length(); item++){ if ( feedback!= null ){ feedback(items[item (items[item], item+1, items.length); 12
Példa II.-App static void Main(){ StaticCallbacks(); InstanceCallbacks(); static void StaticCallbacks() { Set setofitems = new Set(5); setofitems.processitems (null);console.writeline(); setofitems.processitems ( new Set.Feedback(App.FeedbackToConsole) ); Console.WriteLine(); setofitems.processitems ( new Set.Feedback(App.FeedbackToMsgBox) ); Console.WriteLine(); Set.Feedback fb = null; fb += new Set.Feedback(App.FeedbackToConsole); fb += new Set.Feedback(App.FeedbackToMsgBox); setofitems.processitems(fb fb);console.writeline(); static void InstanceCallbacks() { Set setoitems = new Set(5); App appobj = new App(); setoitems.processitems( new Set.Feedback(appobj.FeedbackToFile) ); Console.WriteLine(); 13
Példa II.-App static void FeedbackToConsole(Object value,, Int32 item,, Int32 numitems){ Console.WriteLine("Processing item {0 of {1: {2.", item, numitems, value); static void FeedbackToMsgBox(Object value,, Int32 item,, Int32 numitems){ MessageBox.Show(String.Format("Processing item {0 of {1: {2.", item, numitems, value)); void FeedbackToFile(Object value,, Int32 item,, Int32 numitems){ StreamWriter sw = new StreamWriter("Status", ", true); sw.writeline("processing item {0 of {1: {2.",item,numItems, value); sw.close(); 14
IL kód Nézzük k meg az IL kódot! k feedback( items[item], item+1, items.length ); helyett: IL_001b: callvirt instance void Set/Feedback::Invoke(object Feedback::Invoke(object, int32, int32) 15
MulticastDelegate.Invoke Public Int32 virtual Invoke(Object value, Int32 item,, Int32 numitem ) { if (_prev!= null) _prev.invoke( value, item, numitems ); return _target.methodptr(value, item, numitems 16
Teljes kontroll a delegátum lánc felett public virtual Delegate[] GetInvocationList() Klónozza a lista elemeit egy tömbbe, t de minden elem _prev_ prev-je null. A visszaadott tömbt mbön végigjárhatunk! 17
Példa III class Light{ public String GetPosition() { return "Villany felkapcsolva!"; class Fan{ public String Speed() { throw new Exception("Nagyon gyors!"); class Speaker{ public String Volume() { return "Nagyon hangos!"; 18
Példa III-AppI delegate string GetStatus(); static public void Main() { GetStatus getstatus = null; getstatus += new GetStatus( new Light().GetPosition ); getstatus += new GetStatus( new Fan().Speed ); getstatus += new GetStatus( new Speaker().Volume ); Console.WriteLine( GetComponentStatusReport(getstatus) ); 19
Példa III-AppII static String GetComponentStatusReport(GetStatus status){ if ( status == null) return null; StringBuilder sb = new StringBuilder(); Delegate[] arrayofdelegates = status.getinvocationlist(); foreach( GetStatus getstatus in arrayofdelegates ){ try{ sb.appendformat("{0{1{1", getstatus(), Environment.NewLine); catch(exception e){ Object o = getstatus.target; sb.appendformat("hiba keletkezett: {1{2{0 Hiba: {3{0{0", Environment.NewLine, ((o == null)? "" : o.gettype() + "."), getstatus.method.name, e.message); return sb.tostring(); 20