In C# language and .NET framework, could you help me with understanding delegates?
I was trying to check some code, and found that the results I received were unexpected for me. Here it is:
class Program
{
public static int I = 0;
static Func<string> del = new Func<string>(I.ToString);
static void Main(string[] args)
{
I = 10;
Console.WriteLine("{0}", del());
}
}
The answer was 0, but not 10. Why?
The reason is the following:
The way you declare the delegate it points directly to the
ToStringmethod of the static int instance. It is captured at the time of creation.As flindeberg points out in the comments below, each delegate has a target and a method to be executed on the target.
In this case, the method to be executed is obviously the
ToStringmethod. The interesting part is the instance the method is executed on: It is the instance ofIat the time of the creation, meaning that the delegate is not usingIto get the instance to use but it stores the reference to the instance itself.Later you change
Ito a different value, basically assigning it a new instance. This doesn’t magically change the instance captured in your delegate, why should it?To get the result you expect, you would need to change the delegate to this:
Like this, the delegate points to an anonymous method that executes
ToStringon the currentIat the time of the execution of the delegate.In this case, the method to be executed is an anonymous method created in the class in which the delegate is declared in. The instance is null as it is a static method.
Have a look at the code the compiler generates for the second version of the delegate:
As you can see, it is a normal method that does something. In our case it returns the result of calling
ToStringon the current instance ofI.