C# Delegates, Events, Lambda

  • 1,331 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,331
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
35
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. C#:  Delegates,  Events  and   Lambda   Jussi  Pohjolainen  Tampere  University  of  Applied  Sciences  
  • 2. About  Callbacks  •  Callback  methods  can  be  implemented  in  C#   using  delegates,  events  and  lambda  •  Callback  method?     –  When  buGon  is  clicked,  a  method  is  called  (calls  back   a  method  you  have  implemented)  •  Delegate  type  “points”  to  a  method  or  a  list  of   methods   –  Event  will  help  you  to  build  callback  mechanism  •  Lambda  is  anonymous  method  and  provides   simplified  approach  working  with  delegates  
  • 3. JavaScript:  Callback  function doSomething(integer, someFunction) { var i = 0, s = 0; for(i = 0; i<integer; i = i + 1) { s += integer; } // callback! someFunction(s);}function callBackFunction(result) { print(result is: + result);}function main() { doSomething(5000, callBackFunction);}main();
  • 4. Java  7:  Anonymous  methods  and   callbacks  // Kind of hard?button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // do something }})// Note: Java 8 will have lambda
  • 5. Obj-­‐C:  Selectors  and  Callbacks  - (void) testSelectors{ SEL variable; variable = @selector(animate); [self methodWithSelectorAsArgument: variable];}- (void) methodWithSelectorAsArgument: (SEL) argument{ [self performSelector:argument];}- (void) animate{ ...}
  • 6. Delegate  •  Delegate  type  holds   –  Address  of  the  method  on  which  it  makes  calls   –  Parameters  of  the  method   –  Return  type  of  the  method  •  Works  both  asynchronously  and   synchronously.  Simplifies  things,  no  need  for   Thread  object.  Let’s  see  this  later  
  • 7. Example  // Following delegate type can point to whatever// method as long as its returning int and it has two// parameters.public delegate int Something(int a, int b);// This will generate a following class! Lot of methods// also deriving from MulticastDelegate and Delegate (base class// for MulticastDelegate)sealed class Something : System.MulticastDelegate{ public int Invoke(int x, int y); public IAsyncResult BeginInvoke(int x, int y, AsyncCallback cb, object state); public int EndInvoke(IAsyncResult result);}
  • 8. using System;public delegate int Something(int a, int b);class MyMath{ public int Add(int a, int b) { return a + b; }}class MyMain{ public static void Main() { MyMath m = new MyMath(); Something delegateObject = new Something(m.Add); Console.WriteLine( delegateObject.Invoke(5,5) ); // Calls Invoke! Console.WriteLine( delegateObject(5,5) ); }}
  • 9. using System;public delegate int Something(int a, int b);class MyMath{ public static int Add(int a, int b) { return a + b; }}class MyMain{ public static void Main() { Something delegateObject = new Something(MyMath.Add); // Calls Invoke! Console.WriteLine( delegateObject(5,5) ); }}
  • 10. class MyMain{ public static void Main() { Something delegateObject = new Something(MyMath.Add); PrintInformation(delegateObject); } // All delegates inherite Delegate class public static void PrintInformation(Delegate delObj) { // Remember that delegate may hold number of methods! foreach(Delegate d in delObj.GetInvocationList()) { // Result: Int32 Add(Int32, Int32) Console.WriteLine(d.Method); } }}
  • 11. "REAL  WORLD"  EXAMPLE  
  • 12. class Teacher{ // A new inner class is created here! The class inherits // System.MulticastDelegate // This can point to whatever class that is void and one string // argument. This could be also outer-class. public delegate void TeacherHandler(string msg); // Declare an attribute type of the new class. private TeacherHandler listOfHandlers; // Helper method for assigning the attribute public void RegisterWithListener(TeacherHandler methodToCall) { listOfHandlers = methodToCall; } public bool teacherIsBoring { get; set; } public void teach() { // If teacher is not boring if(!teacherIsBoring) { // And there are someone listening if(listOfHandlers != null) { // Send message to the listener. listOfHandlers("C# is cool!"); } } }}
  • 13. using System;class MyMain{ public static void Main() { Teacher jussi = new Teacher(); // instantiate inner class object jussi.RegisterWithListener(new Teacher.TeacherHandler(OnTeachEvent)); jussi.teacherIsBoring = false; jussi.teach(); } // Since teacher is not boring and we are listening, // this method is called public static void OnTeachEvent(string m) { Console.WriteLine("Important message from teacher!"); Console.WriteLine(m); }}
  • 14. MULTICASTING  
  • 15. // Helper method for assigning the attribute public void RegisterWithListener(TeacherHandler methodToCall) { if(listOfHandlers == null) { listOfHandlers = methodToCall; } else { Delegate.Combine(listOfHandlers, methodToCall); } }… Teacher jussi = new Teacher(); // instantiate inner class object jussi.RegisterWithListener(new Teacher.TeacherHandler(OnTeachEvent1)); jussi.RegisterWithListener(new Teacher.TeacherHandler(OnTeachEvent2)); jussi.teacherIsBoring = false; jussi.teach();
  • 16. // Helper method for assigning the attribute public void RegisterWithListener(TeacherHandler methodToCall) { // And even more easier! listOfHandlers += methodToCall; }… Teacher jussi = new Teacher(); // instantiate inner class object jussi.RegisterWithListener(new Teacher.TeacherHandler(OnTeachEvent1)); jussi.RegisterWithListener(new Teacher.TeacherHandler(OnTeachEvent2)); jussi.teacherIsBoring = false; jussi.teach();
  • 17. REMOVING  TARGETS  
  • 18. class MyMain{ public static void Main() { Teacher jussi = new Teacher(); // instantiate inner class object jussi.RegisterWithListener(new Teacher.TeacherHandler(OnTeachEvent1)); Teacher.TeacherHandler listener; jussi.RegisterWithListener(listener = new Teacher.TeacherHandler(OnTeachEvent2)); jussi.teacherIsBoring = false; jussi.teach(); jussi.UnRegisterWithListener(listener); jussi.teach(); }.. // Helper method for assigning the attribute public void UnRegisterWithListener(TeacherHandler methodToCall) { listOfHandlers -= methodToCall; }
  • 19. METHOD  GROUP  CONVERSION  
  • 20. Method  Group  Conversion  •  In  the  previous  example,  we  created  object   –  Teacher.TeacherHandler  •  You  dont  have  to  do  this!  •  Method  group  conversion!   –  Direct  method  name  is  converted  to  a  delegate   object  
  • 21. Method  Group  Conversion  public static void Main(){ Teacher jussi = new Teacher(); jussi.RegisterWithListener(OnTeachEvent1); jussi.RegisterWithListener(OnTeachEvent2); jussi.teacherIsBoring = false; jussi.teach(); jussi.UnRegisterWithListener(OnTeachEvent2); jussi.teach();}
  • 22. EVENTS  
  • 23. Simplify  Registering  •  The  previous  example  had  methods  like   –  public  void  RegisterWithListener(TeacherHandler   methodToCall)   –  public  void   UnRegisterWithListener(TeacherHandler   methodToCall)  •  To  simplify  this,  we  can  use  events!  
  • 24. class Teacher{ private int workHoursPerDay = 0; public delegate void TeacherHandler(string msg); // No register or unregister methods! // When using events, two hidden methods are generated: // add_AboutToOverload // remove_AboutToOverLoad public event TeacherHandler AboutToOverload; public event TeacherHandler MentallyDead; public void teach() { workHoursPerDay++; if(workHoursPerDay >= 4 && workHoursPerDay < 6) { if(AboutToOverload != null) { AboutToOverload("TOO MUCH WORK FOR ME! Workhours = " + workHoursPerDay); } } else if(workHoursPerDay >= 6) { if(MentallyDead != null) { MentallyDead("CANNOT WORK ANYMORE, BITCH ABOUT THIS! Workhours = " + workHoursPerDay); } } }}
  • 25. class MyMain{ public static void Main() { Student pekka = new Student(); pekka.Name = "Pekka"; Supervisor jaska = new Supervisor(); jaska.Name = "Jaska"; Teacher jussi = new Teacher(); jussi.AboutToOverload += pekka.listen; jussi.AboutToOverload += jaska.listen; jussi.MentallyDead += jaska.listen; jussi.teach(); jussi.teach(); jussi.teach(); jussi.teach(); jussi.teach(); jussi.teach(); jussi.teach(); jussi.teach(); }}
  • 26. class Student{ public string Name {get; set;} public void listen(string m) { Console.WriteLine(Name + " listening to teacher msg = " + m); }}class Supervisor{ public string Name {get; set;} public void listen(string m) { Console.WriteLine(Name + " listening to teacher msg = " + m); }}
  • 27. RECOMMEND  EVENT  PATTERN  
  • 28. class Student{ public string Name {get; set;} // Listener here get information: // 1) who is the sender? // 2) more information about the event public void listen(object sender, TeacherEventArgs events) { Console.WriteLine(Name + " listening to teacher msg = " + events.msg); }}class Supervisor{ public string Name {get; set;} public void listen(object sender, TeacherEventArgs events) { Console.WriteLine(Name + " listening to teacher msg = " + events.msg); }}
  • 29. // Implement own custom event!public class TeacherEventArgs : EventArgs{ public readonly string msg; public TeacherEventArgs(string message) { msg = message; }}// And use itclass Teacher{ private int workHoursPerDay = 0; public delegate void TeacherHandler(object sender, TeacherEventArgs e); … public void teach() { … AboutToOverload(this, new TeacherEventArgs("TOO MUCH WORK …")); … }
  • 30. EVENTHANDLER<T>  DELEGATE  
  • 31. public class TeacherEventArgs : EventArgs{ public readonly string msg; public TeacherEventArgs(string message) { msg = message; }}class Teacher{ private int workHoursPerDay = 0; /* public delegate void TeacherHandler(object sender, TeacherEventArgs e); public event TeacherHandler AboutToOverload; public event TeacherHandler MentallyDead; */ // Now we can use the EventHandler class. Notice that there is no // need for the delegate anymore! public event EventHandler<TeacherEventArgs> AboutToOverload; public event EventHandler<TeacherEventArgs> MentallyDead;
  • 32. class MyMain{ public static void Main() { Student pekka = new Student(); pekka.Name = "Pekka"; Supervisor jaska = new Supervisor(); jaska.Name = "Jaska"; Teacher jussi = new Teacher(); // Now we can use the EventHandler class! jussi.AboutToOverload += new EventHandler<TeacherEventArgs>(pekka.listen); jussi.AboutToOverload += jaska.listen; jussi.MentallyDead += jaska.listen;
  • 33. Anonymous  Delegate  Methods  Teacher jussi = new Teacher();jussi.AboutToOverload += delegate (object send, TeacherEventArgs events){ Console.WriteLine("anonymous delegate method 1!");};jussi.AboutToOverload += delegate{ Console.WriteLine("anonymous delegate method 2!");};
  • 34. ABOUT  LAMBDA  
  • 35. Lambda  Expressions  •  Lambda  expression  is  an  anonymous  funcon   that  you  can  use  to  create  delegates  •  Can  be  used  to  write  local  funcons  that  can   be  passed  as  arguments  •  Helpful  for  wring  LINQ  query  expressions  (we   will  see  this  later,  maybe  J)    jussi.AboutToOverload += (object sender, TeacherEventArgs events) => Console.WriteLine("hello");
  • 36. COLLECTIONS  
  • 37. System.Collecons  •  All  Collecon  classes  can  be  found  from   System.Collecons  •  Classes  like   –  ArrayList   –  Hashtable     •  key/value   –  Queue   •  FIFO:  first-­‐in,  first-­‐out   –  SortedList   •  key/value,  sorted  by  the  keys   –  Stack   •  last-­‐in,  first-­‐out  
  • 38. Example    ArrayList list = new ArrayList();list.Add("a");list.Add("b");list.add("c");foreach(string s in list) { … }
  • 39. Using  Generics  ArrayList<string> list = newArrayList<string>();list.Add("a");list.Add("b");list.add("c");list.add(2); // Failsforeach(string s in list) { … }
  • 40. Use  interfaces  •  Use  this   –  IList<string> list = new ArrayList<string>();•  Instead  of  this   –  ArrayList<string> list = new Arraylist();•  You  can  change  the  collecon  class  later!  
  • 41. ABOUT  THREADS  
  • 42. Threading  •  Ability  to  multask  •  Process  -­‐>  UI-­‐thread  -­‐>  other  threads  •  Use  System.Threading  •  Do  exercises  to  learn  about  threading!