What is a .NET generic delegate?
Posted: (EET/GMT+2)
If you are using C# 3.0 already, you've no doubt also trying out lambda expressions. However, lambda expressions are often seen in LINQ statements, but they are also useful elsewhere.
To help with this, the System namespace (in the System.Core assembly) defines several so-called generic delegates, such as one called "Func". These generic delegates let you easily define delegates with common signatures, such as a delegate taking one parameter and returning a value. Since generics are supported, you can also specify those datatypes that you want.
Here's an example. Say, you wanted to quickly implement a method to convert an integer value to a string. Furthermore, you might need to pass this method as a parameter (delegate) to another method. To do this, you could use the Func<T, TResult> generic delegate, and define the method like this using a lambda expression:
Funcconvert = num => num.ToString();
Now, you have defined the method "convert", which takes in an int and returns a string. In case you are interested, here's the CIL (Common Intermediate Language) of the above C# code:
.method private hidebysig instance void button1_Click(
object sender, class [mscorlib]System.EventArgs e)
cil managed
{
.maxstack 3
.locals init ([0] class [System.Core]
System.Func`2 convert,
[1] int32 'value',
[2] string str)
IL_0000: nop
IL_0001: ldsfld class [System.Core]System.
Func`2 WinFormsTestApp.Form2::
'CS$<>9__CachedAnonymousMethodDelegate4'
IL_0006: brtrue.s IL_001b
IL_0008: ldnull
IL_0009: ldftn string WinFormsTestApp.Form2::
'b__3'(int32)
IL_000f: newobj instance void class [System.Core]
System.Func`2::.ctor(object,
native int)
IL_0014: stsfld class [System.Core]
System.Func`2 WinFormsTestApp.Form2::
'CS$<>9__CachedAnonymousMethodDelegate4'
IL_0019: br.s IL_001b
IL_001b: ldsfld class [System.Core]
System.Func`2 WinFormsTestApp.Form2::
'CS$<>9__CachedAnonymousMethodDelegate4'
IL_0020: stloc.0
IL_0021: ldc.i4.s 123
IL_0023: stloc.1
IL_0024: ldloc.0
IL_0025: ldloc.1
IL_0026: callvirt instance !1 class [System.Core]
System.Func`2::Invoke(!0)
IL_002b: stloc.2
IL_002c: ldloc.2
IL_002d: call valuetype [System.Windows.Forms]
System.Windows.Forms.DialogResult [System.Windows.Forms]
System.Windows.Forms.MessageBox::Show(string)
IL_0032: pop
IL_0033: ret
}
-------
.field private static class [System.Core]
System.Func`2
'CS$<>9__CachedAnonymousMethodDelegate4'
.custom instance void [mscorlib]
System.Runtime.CompilerServices.
CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
-------
.method private hidebysig static string
'b__3'(int32 num) cil managed
{
.custom instance void [mscorlib]System.Runtime.
CompilerServices.CompilerGeneratedAttribute::
.ctor() = ( 01 00 00 00 )
// Code size 12 (0xc)
.maxstack 1
.locals init ([0] string CS$1$0000)
IL_0000: ldarga.s num
IL_0002: call instance string [mscorlib]
System.Int32::ToString()
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
}
Being able to use delegates properly is a great aid in many C#/.NET programming situations. Combining lambda expressions and generic delegates to the equation gives you a powerful set of tools.