Methods are delegate types. It is that simple. Since delegates are types in .NET we can use any method as types, that means we can pass methods as parameters and we can return methods.
The below code shows different ways we can instantiate a delegate.
1: namespace DelegatesVsInterfaces
2: {
3: public delegate string MyDelegate(string param);
4:
5: class Program
6: {
7: static void Main(string[] args)
8: {
9: // delegate initialization based on history
10:
11: // C# 1.0
12: MyDelegate md1 = new MyDelegate(MyMethod);
13: Console.WriteLine(md1("C# 1.0"));
14:
15: // C# 2.0
16: MyDelegate md2 = MyMethod;
17: Console.WriteLine(md2("C# 2.0"));
18:
19: // C# 2.0 - anonymous method
20: MyDelegate md3 = delegate(string message)
21: {
22: return String.Format("Your message, {0} - from anonymous method",message);
23: };
24: Console.WriteLine(md3("C# 2.0 and later"));
25:
26: // C# 3.0 - lamda expressions
27: MyDelegate md4 = message =>
28: {
29: return String.Format("Your message, {0} - from lamda methods", message);
30: };
31: Console.WriteLine(md4("C# 3.0 and later"));
32:
33: Console.ReadKey();
34: }
35:
36: public static string MyMethod(string greeting)
37: {
38: //Thread.Sleep(5000);
39: return String.Format("Your message, {0} - relayed from MyMethod",greeting);
40: }
41: }
42: }
A delegate has different ways of invocation. The very direct way is calling the delegate itself with the parameters. This indirectly invokes the Invoke() method of the delegate. Invoke() is generated by the compiler with the correct parameter list.
The following code shows the direct invocation.
1: string result = md1("parameter");
2: result = md1.Invoke("parameter");
Other way of handling a delegate invocation is, invoking the method asynchronously. BeginInvoke() and EndInvoke() of a delegate is used for this.
BeginInvoke() is generated for a delegate with that specific delegate’s parameters as first set of parameters, next parameter is a AsyncCallback type method and last one is a object which could have values to the callback method.
The following code explains how to use the BeginInvoke() and EndInvoke() to asynchronous execution.
1: // put this in your method invocation code
2: MyDelegate md = MyMethod;
3: AsyncCallback callback = CallBackMethod;
4:
5: IAsyncResult result = md.BeginInvoke("Param", callback, null);
6:
7:
8: // callback method
9: public static void CallBackMethod(IAsyncResult result)
10: {
11: AsyncResult asyncResult = (AsyncResult)result;
12: MyDelegate caller = (MyDelegate)asyncResult.AsyncDelegate;
13:
14: string value = caller.EndInvoke(result);
15:
16: Console.WriteLine(value);
17: }
If the method hasn’t finished the execution when the EndInvoke() is called, the callback method waits till the execution is finished.
Another way of invoking a delegate is by using its DynamicInvoke(). More often this is direct as Invoke(), but has the difference in the parameters passed to the delegate. DynamicInvoke() has a object array parameter. We should pass the parameters with the correct data types and it should be with the correct parameter count. If the parameter is not correct it will throw an ArgumentException and if the number of parameters doesn’t match it will throw TargetParameterCountException.