C# · CodeProject · Dotnet

Delegates internals

Dear Reader,

Today i was just digging inside the delegates ex: Action and anonymous delegates via lambda expression. So i kinda started to ask few curious questions to myself and thus set out to dig inside to answer them. While doing so, i found few interesting things which i would like to share with you all. Hope it is useful:

First i wrote a sample code as shown below:

Action del = () => Console.WriteLine(“Hello”);

Well yes the code is very simple, but i started to wonder and asked a question myself as whats the difference between the above 2 different style of delegate invocation.

If in case you’re not aware, every delegate internally is represented as a class type having just 4 important methods i.e BeginInvoke, Invoke, EndInvoke and Ctor. There is nothing much to explain about these methods.

I looked inside the IL and came to know that the above 2 styles of delegate invocation is in fact same. The compiler just converts del() to del.Invoke(). So there will be 2 del.Invoke() statements as shown in below IL opcodes:

IL_0022: callvirt instance void [mscorlib]System.Action::Invoke()
IL_0027: nop
IL_0028: ldloc.0
IL_0029: callvirt instance void [mscorlib]System.Action::Invoke()

Next i asked myself how lambda expression used above are treated internally. I found out that the lambda expression which i was using in the code is treated as a class internally in the IL. The below code produced 2 class for the anonymous delegates i have used:

MyDelegate del = () => (2 + 2).ToString();
del = () => (4 + 4).ToString();\

Lets look into the IL and see what charm the compiler has done:

// Fields
.field private static class ConsoleApplication.Program/MyDelegate ‘CS$<>9__CachedAnonymousMethodDelegate2’
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
.field private static class ConsoleApplication.Program/MyDelegate ‘CS$<>9__CachedAnonymousMethodDelegate3’
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00

As you can see it has produced 2 class for each of those anonymous delegates with a name as shown above. No matter where the anonymous delegates are declared, they do get the same naming styles. But i still wonder and looking for an answer why all anonymous delegates are prefixed with CS$<>9__ word? May be Microsoft chose to keep it that way? No idea! If you know, kindly leave a comment.

That’s all i could find so far, i shall surely share more if i found out more 🙂


P.S: Your comment/vote are much appreciated 🙂


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s