Wednesday, December 2, 2015

C# delegate

Delegates C#

In simple words it is instance referencing to a method.
eg: Suppose there is a method int method1(int x){}
Create a delegate instance: delegate int delegateInstance(int k);
Assign this delegate instance to method1: delegateInstance instance1=method1
Now when we call this delegate method, it will actually call the method1: instance1(3), it will call method1(3).

Arithmetic can also be done on the delegate method assignment. eg:
instance1+=method2;
Now when the instance1 is called, it will call both method1 and method2 in order.
We can also do instance1-=method1. Now when instance1 is called, it will only call method2.
When a delegate method is assigned to a class method, it also maintains the reference to the method. In case of static method, it maintains null
eg:delegateInstance instance1=method1
  instance1.Target == this  //true
  instance1.Method; // Int32 method1(Int32)

  
Generic delegate:
public delegate T Transformer<T> (T arg);
public class Util
{
  public static void Transform<T> (T[] values,Transformer<T> t)
  {
    for (int i = 0; i < values.Length; i++)
      values[i] = t(values[i]);
  }
}

class Test
{
  static void Main(  )
  {
    int[] values = new int[] {1, 2, 3};
    Util.Transform(values, Square);      // dynamically hook in Square
    foreach (int i in values)
      Console.Write (i + "  ");           // 1   4   9
  }

  static int Square (int x) { return x * x; }
}

A delegate design may be a better choice than an interface design if one or more of these conditions are true:
The interface defines only a single method
Multicast capability is needed(calling more than one methods at a time. Hit: +=)
The listener needs to implement the interface multiple times  

Assigning one delegate instance to another results in compile time error. They are incompatible to each other.
D d1=m1;
D d2=d1; //Compile time error

Two delegates pointing to same method are equal.
  delegate void d();
  D d1=m1;
  D d2=m1;
  d1==d2; //true

A delegate method can be assigned with method instance which takes more wide parameter. Eg if delegate is for parameter class c1. We can assign a method which accepts super class of class c1. This is called contravariance.
delegate void SpecificDelegate (SpecificClass s);
class SpecificClass {}
class Test
{
  static void Main(  )
  {
    SpecificDelegate specificDelegate = GeneralHandler;
    specificDelegate (new SpecificClass(  ));
  }
  static void GeneralHandler(object o)
  {
    Console.WriteLine(o.GetType(  )); // SpecificClass
  }
}

the return type of a delegate can be super class of the return type of its target method. This is called covariance.
eg delegate Asset DebtCollector(  );
class Asset {}
class House : Asset {}
class Test
{
  static void Main(  )
  {
     DebtCollector d = new DebtCollector (GetHomeSweetHome);
     Asset a = d(  );
     Console.WriteLine(a.GetType(  )); // House
  }
  static House GetHomeSweetHome() {return new House(  ); }
}

Reference: https://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx

No comments:

Post a Comment