Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using delegates in C#

Tags:

c#

.net

delegates

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?

like image 869
user1859587 Avatar asked Nov 28 '12 11:11

user1859587


People also ask

What is the use of delegates?

Delegates allow methods to be passed as parameters. Delegates can be used to define callback methods. Delegates can be chained together; for example, multiple methods can be called on a single event. Methods don't have to match the delegate type exactly.

What are the advantages of using delegates in C#?

Advantages to using them in design:Allow you to develop libraries and classes that are easily extensible, since it provides an easy way to hook in other functionality (for example, a where clause in LINQ can use a delegate [Func<T,bool>] to filter on, without having to write new code in the Where method.

How do you write a delegate?

A delegate can be declared using the delegate keyword followed by a function signature, as shown below. The following declares a delegate named MyDelegate . public delegate void MyDelegate(string msg); Above, we have declared a delegate MyDelegate with a void return type and a string parameter.

How many types of delegates are there in C#?

What are types of delegates in C#? There are two types of delegates, singlecast delegates, and multiplecast delegates. Singlecast delegate point to single method at a time. In this the delegate is assigned to a single method at a time.


1 Answers

The reason is the following:

The way you declare the delegate it points directly to the ToString method 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 ToString method. The interesting part is the instance the method is executed on: It is the instance of I at the time of the creation, meaning that the delegate is not using I to get the instance to use but it stores the reference to the instance itself.

Later you change I to 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:

static Func<string> del = new Func<string>(() => I.ToString()); 

Like this, the delegate points to an anonymous method that executes ToString on the current I at 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:

private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0); private static string cctor>b__0() {     return UserQuery.I.ToString(); } 

As you can see, it is a normal method that does something. In our case it returns the result of calling ToString on the current instance of I.

like image 83
Daniel Hilgarth Avatar answered Oct 09 '22 10:10

Daniel Hilgarth