Late Binding Delegates: A delegate is a repository of type-safe function pointers.

image_pdfimage_print
   
 

using System;
using System.Reflection;

delegate void XDelegate(int arga, int argb);

class MyClass {
    public void MethodA(int arga, int argb) {
        Console.WriteLine("MyClass.MethodA called: {0} {1}", arga, argb);
    }
}

class Starter {
    static void Main() {
        MyClass obj = new MyClass();
        XDelegate delObj = new XDelegate(obj.MethodA);
        delObj.Invoke(1, 2);
        delObj(3, 4);
    }
}

    


Define your own delegate

image_pdfimage_print

   

/*
Learning C# 
by Jesse Liberty

Publisher: O'Reilly 
ISBN: 0596003765
*/
 using System;

 namespace DelegatesAndEvents
 {
     class MyClassWithDelegate
     {
         // The delegate declaration.
         public delegate void StringDelegate(string s);

     }

     class MyImplementingClass
     {
         public static void WriteString(string s)
         {
             Console.WriteLine("Writing string {0}", s);
         }

         public static void LogString(string s)
         {
             Console.WriteLine("Logging string {0}", s);
         }

         public static void TransmitString(string s)
         {
             Console.WriteLine("Transmitting string {0}", s);
         }

     }

    public class TesterDelegatesAndEvents
    {
       public void Run()
       {
           // Define three StringDelegate objects.
           MyClassWithDelegate.StringDelegate
               Writer, Logger, Transmitter;

           // Define another StringDelegate
           // to act as the multicast delegate.
           MyClassWithDelegate.StringDelegate
               myMulticastDelegate;

           // Instantiate the first three delegates,
           // passing in methods to encapsulate.
           Writer = new MyClassWithDelegate.StringDelegate(
               MyImplementingClass.WriteString);
           Logger = new MyClassWithDelegate.StringDelegate(
               MyImplementingClass.LogString);
           Transmitter =
               new MyClassWithDelegate.StringDelegate(
               MyImplementingClass.TransmitString);

           // Invoke the Writer delegate method.
           Writer("String passed to Writer
");

           // Invoke the Logger delegate method.
           Logger("String passed to Logger
");

           // Invoke the Transmitter delegate method.
           Transmitter("String passed to Transmitter
");

           // Tell the user you are about to combine
           // two delegates into the multicast delegate.
           Console.WriteLine(
               "myMulticastDelegate = Writer + Logger");

           // Combine the two delegates;  assign the result
           // to myMulticastDelegate
           myMulticastDelegate = Writer + Logger;

           // Call the delegated methods; two methods
           // will be invoked.
           myMulticastDelegate(
               "First string passed to Collector");

           // Tell the user you are about to add
           // a third delegate to the multicast.
           Console.WriteLine(
               "
myMulticastDelegate += Transmitter");

           // Add the third delegate.
           myMulticastDelegate += Transmitter;

           // Invoke the three delegated methods.
           myMulticastDelegate(
               "Second string passed to Collector");

           // Tell the user you are about to remove
           // the Logger delegate.
           Console.WriteLine(
               "
myMulticastDelegate -= Logger");

           // Remove the Logger delegate.
           myMulticastDelegate -= Logger;

           // Invoke the two remaining delegated methods.

           myMulticastDelegate(
               "Third string passed to Collector");
       }

       [STAThread]
       static void Main()
       {
          TesterDelegatesAndEvents t = new TesterDelegatesAndEvents();
          t.Run();
       }
    }
 }

           
          


Chaining events.

image_pdfimage_print
   
 


using System;

public class EventTestClass {
    private int nValue;
    public delegate void ValueChangedEventHandler();
    public event ValueChangedEventHandler Changed;
    protected virtual void OnChanged() {
        if (Changed != null)
            Changed();
        else
            Console.WriteLine("Event fired. No handler!");
    }

    public EventTestClass(int nValue) {
        SetValue(nValue);
    }
    public void SetValue(int nV) {
        if (nValue != nV) {
            nValue = nV;
            OnChanged();
        }
    }
}

public class Mainclass {
    public void HandleChange1() {
        Console.WriteLine("Handler 1 Called");
    }
    public void HandleChange2() {
        Console.WriteLine("Handler 2 Called");
    }
    public Mainclass() {
    }

    public static void Main() {
        EventTestClass etc = new EventTestClass(3);
        Mainclass app = new Mainclass();

        etc.Changed += new EventTestClass.ValueChangedEventHandler(app.HandleChange1);
        etc.Changed += new EventTestClass.ValueChangedEventHandler(app.HandleChange2);

        etc.SetValue(5);
        etc.SetValue(5);
        etc.SetValue(3);
    }
}

    


Delegates And Events 2

image_pdfimage_print

/*
Learning C#
by Jesse Liberty

Publisher: O'Reilly
ISBN: 0596003765
*/
using System;

namespace DelegatesAndEvents
{
public enum comparison
{
theFirstComesFirst = 1,
theSecondComesFirst = 2
}

// A simple collection to hold two items.
class Pair
{
// Private array to hold the two objects.
private object[] thePair = new object[2];

// The delegate declaration.
public delegate comparison
WhichIsFirst(object obj1, object obj2);

// Passed in constructor takes two objects,
// added in order received.
public Pair(
object firstObject,
object secondObject)
{
thePair[0] = firstObject;
thePair[1] = secondObject;
}

// Public method that orders
// the two objects by whatever criteria the objects like!
public void Sort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1])
== comparison.theSecondComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}

// Public method that orders
// the two objects by the reverse of whatever criteria
// the objects like!
public void ReverseSort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theFirstComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}

// Ask the two objects to give their string value.
public override string ToString()
{
return thePair[0].ToString() + “, ”
+ thePair[1].ToString();
}
}

class Dog
{
private int weight;

// A static delegate.
public static readonly Pair.WhichIsFirst OrderDogs =
new Pair.WhichIsFirst(Dog. WhichDogComesFirst);

public Dog(int weight)
{
this.weight=weight;
}

// Dogs are sorted by weight.
public static comparison WhichDogComesFirst(
Object o1, Object o2)
{
Dog d1 = (Dog) o1;
Dog d2 = (Dog) o2;
return d1.weight > d2.weight ?
comparison.theSecondComesFirst :
comparison.theFirstComesFirst;
}
public override string ToString()
{
return weight.ToString();
}
}

class Student
{
private string name;

// A static delegate.
public static readonly Pair.WhichIsFirst OrderStudents =
new Pair.WhichIsFirst(Student.WhichStudentComesFirst);

public Student(string name)
{
this.name = name;
}

// Students are sorted alphabetically.
public static comparison
WhichStudentComesFirst(Object o1, Object o2)
{
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return (String.Compare(s1.name, s2.name) < 0 ? comparison.theFirstComesFirst : comparison.theSecondComesFirst); } public override string ToString() { return name; } } public class TesterDelegatesAndEvents1 { public void Run() { // Create two students and two dogs // and add them to Pair objects. Student Jesse = new Student("Jesse"); Student Stacey = new Student ("Stacey"); Dog Milo = new Dog(65); Dog Fred = new Dog(12); // Create the Pair object. Pair studentPair = new Pair(Jesse,Stacey); Pair dogPair = new Pair(Milo, Fred); Console.WriteLine("studentPair : {0}", studentPair.ToString()); Console.WriteLine("dogPair : {0}", dogPair.ToString()); // Tell the student Pair to sort itself, // passing in the Student delegate. studentPair.Sort(Student.OrderStudents); Console.WriteLine("After Sort studentPair : {0}", studentPair.ToString()); studentPair.ReverseSort(Student.OrderStudents); Console.WriteLine("After ReverseSort studentPair : {0}", studentPair.ToString()); // Tell the Dog pair to sort itself, // passing in the Dog delegate. dogPair.Sort(Dog.OrderDogs); Console.WriteLine("After Sort dogPair : {0}", dogPair.ToString()); dogPair.ReverseSort(Dog.OrderDogs); Console.WriteLine("After ReverseSort dogPair : {0}", dogPair.ToString()); } [STAThread] static void Main() { TesterDelegatesAndEvents1 t = new TesterDelegatesAndEvents1(); t.Run(); } } } [/csharp]

Delegates And Events

image_pdfimage_print

/*
Learning C#
by Jesse Liberty

Publisher: O'Reilly
ISBN: 0596003765
*/
using System;

namespace DelegatesAndEvents
{
public enum comparison
{
theFirstComesFirst = 1,
theSecondComesFirst = 2
}

// A simple collection to hold two items
class Pair
{
// Private array to hold the two objects
private object[] thePair = new object[2];

// The delegate declaration
public delegate comparison
WhichIsFirst(object obj1, object obj2);

// Passed in constructor takes two objects,
// added in order received
public Pair(
object firstObject,
object secondObject)
{
thePair[0] = firstObject;
thePair[1] = secondObject;
}

// Public method that orders the
// two objects by whatever criteria the objects like!
public void Sort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1])
== comparison.theSecondComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}

// Public method that orders the
// two objects by the reverse of whatever criteria the
// objects likes!
public void ReverseSort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theFirstComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}

// Ask the two objects to give their string value
public override string ToString()
{
return thePair[0].ToString() + “, ”
+ thePair[1].ToString();
}
}

class Dog
{
private int weight;

public Dog(int weight)
{
this.weight=weight;
}

// dogs are sorted by weight
public static comparison WhichDogComesFirst(
Object o1, Object o2)
{
Dog d1 = (Dog) o1;
Dog d2 = (Dog) o2;
return d1.weight > d2.weight ?
comparison.theSecondComesFirst :
comparison.theFirstComesFirst;
}
public override string ToString()
{
return weight.ToString();
}
}

class Student
{
private string name;
public Student(string name)
{
this.name = name;
}

// Students are sorted alphabetically
public static comparison
WhichStudentComesFirst(Object o1, Object o2)
{
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return (String.Compare(s1.name, s2.name) < 0 ? comparison.theFirstComesFirst : comparison.theSecondComesFirst); } public override string ToString() { return name; } } public class TesterDelegatesAndEvents11 { public void Run() { // Create two students and two dogs // and add them to Pair objects Student Jesse = new Student("Jesse"); Student Stacey = new Student ("Stacey"); Dog Milo = new Dog(65); Dog Fred = new Dog(12); Pair studentPair = new Pair(Jesse,Stacey); Pair dogPair = new Pair(Milo, Fred); Console.WriteLine("studentPair : {0}", studentPair.ToString()); Console.WriteLine("dogPair : {0}", dogPair.ToString()); // Instantiate the delegates Pair.WhichIsFirst theStudentDelegate = new Pair.WhichIsFirst( Student.WhichStudentComesFirst); Pair.WhichIsFirst theDogDelegate = new Pair.WhichIsFirst( Dog.WhichDogComesFirst); // Sort using the delegates studentPair.Sort(theStudentDelegate); Console.WriteLine("After Sort studentPair : {0}", studentPair.ToString()); studentPair.ReverseSort(theStudentDelegate); Console.WriteLine("After ReverseSort studentPair : {0}", studentPair.ToString()); dogPair.Sort(theDogDelegate); Console.WriteLine("After Sort dogPair : {0}", dogPair.ToString()); dogPair.ReverseSort(theDogDelegate); Console.WriteLine("After ReverseSort dogPair : {0}", dogPair.ToString()); } static void Main() { TesterDelegatesAndEvents11 t = new TesterDelegatesAndEvents11(); t.Run(); } } } [/csharp]

Events: Custom Add and Remove

image_pdfimage_print

   

/*
A Programmer&#039;s Introduction to C# (Second Edition)
by Eric Gunnerson

Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/

// 23 - EventsCustom Add and Remove
// copyright 2000 Eric Gunnerson
using System;
using System.Collections;
using System.Runtime.CompilerServices;


public class EventsCustomAddandRemove
{
    static public void ButtonHandler(object sender, EventArgs e)
    {
        Console.WriteLine("Button clicked");
    }
    
    public static void Main()
    {
        Button button = new Button();
        
        button.Click += new Button.ClickHandler(ButtonHandler);
        
        button.SimulateClick();
        
        button.Click -= new Button.ClickHandler(ButtonHandler);
        
        button.TearDown();
    }
}

//
// Global delegate cache. Uses a two-level hashtable. The delegateStore hashtable 
// stores a hashtable keyed on the object instance, and the instance hashtable is 
// keyed on the unique key. This allows fast tear-down of the object when it&#039;s destroyed.
//
public class DelegateCache
{
    private DelegateCache() {}    // nobody can create one of these
    
    Hashtable delegateStore = new Hashtable();    // top level hash table
    
    static DelegateCache dc = new DelegateCache();    // our single instance
    
    Hashtable GetInstanceHash(object instance)
    {
        Hashtable instanceHash = (Hashtable) delegateStore[instance];
        
        if (instanceHash == null)
        {
            instanceHash = new Hashtable();
            delegateStore[instance] = instanceHash;
            
        }
        return(instanceHash);
    }
    
    public static void Combine(Delegate myDelegate, object instance, object key)
    {
        lock(instance)
        {
            Hashtable instanceHash = dc.GetInstanceHash(instance);        
            
            instanceHash[key] = Delegate.Combine((Delegate) instanceHash[key],
            myDelegate);
        }
    }
    
    public static void Remove(Delegate myDelegate, object instance, object key)
    {
        lock(instance)
        {
            Hashtable instanceHash = dc.GetInstanceHash(instance);        
            
            instanceHash[key] = Delegate.Remove((Delegate) instanceHash[key],
            myDelegate);
        }
    }
    
    public static Delegate Fetch(object instance, object key)
    {
        Hashtable instanceHash = dc.GetInstanceHash(instance);        
        
        return((Delegate) instanceHash[key]);
    }
    
    public static void ClearDelegates(object instance)
    {
        dc.delegateStore.Remove(instance);
    }
}

public class Button
{
    public void TearDown()
    {
        DelegateCache.ClearDelegates(this);
    }
    
    
    public delegate void ClickHandler(object sender, EventArgs e);
    
    static object clickEventKey = new object();
    
    public event ClickHandler Click
    {
        add
        {
            DelegateCache.Combine(value, this, clickEventKey);
        }
        
        remove
        {
            DelegateCache.Remove(value, this, clickEventKey);
        }
    }
    
    protected void OnClick()
    {
        ClickHandler ch = (ClickHandler) DelegateCache.Fetch(this, clickEventKey);
        
        if (ch != null)
        ch(this, null);
    }
    
    public void SimulateClick()
    {
        OnClick();
    }
}

           
          


Events:Add and Remove Functions 2

image_pdfimage_print

   

using System;

public class AddandRemoveFunctions2
{
    static public void ButtonHandler(object sender, EventArgs e)
    {
        Console.WriteLine("Button clicked");
    }
    
    public static void Main()
    {
        Button button = new Button();
        
        button.Click += new Button.ClickHandler(ButtonHandler);
        
        button.SimulateClick();
        
        button.Click -= new Button.ClickHandler(ButtonHandler);
    }
}

public class Button
{
    public delegate void ClickHandler(object sender, EventArgs e);
    
    public event ClickHandler Click;
    
    protected void OnClick()
    {
        if (Click != null)
        Click(this, null);
    }
    
    public void SimulateClick()
    {
        OnClick();
    }
}