Delegates and events are widely used in the. NET Framework, but better understanding of delegates and events is not easy for many people who have been in contact with C # for a long time. They are like a threshold, through the threshold of the people, think it is too easy, and no past people every time to see the delegates and events feel the heart is blocked, uncomfortable. In this chapter, I'll talk about what delegates are, why they use delegates, the origins of events, the delegates and events in the. NET Framework, the handling of method exceptions and timeouts in delegates, delegate and asynchronous programming, delegates, and events for observer design patterns. The compilation of their code is also discussed.
1.1 Understanding delegation
1.1.1 The method as a parameter to the method
Let's take a look at the following two simplest ways, regardless of how the title is bypassed, or what the delegate is, but to print a greeting on the screen:
public void Greetpeople (string name)
{
englishgreeting (name);
}
public void Englishgreeting (string name)
{
Console.WriteLine ("Good Morning," + name);
}
Whether or not these two methods have any practical significance aside. Greetpeople is used to say hello to someone when we pass the name parameter representing someone's name, such as "Liker" in, in this method, the Englishgreeting method is invoked, the name parameter is passed again, englishgreeting is used to output "Good morning, Liker" to the screen.
Now assume that this program needs to be globalized, alas, I am a Chinese, I do not understand the "Good morning" is what meaning, how to do it. Well, let's add a Chinese greeting:
public void Chinesegreeting (string name)
{
Console.WriteLine ("Good Morning," + name);
}
At this time, Greetpeople also need to change a change, or how to determine the version of the greeting greeting the appropriate way. Before doing this, we'd better define an enumeration as a basis for judgment:
Public enum Language
{
中文版, Chinese
}
public void Greetpeople (string name, Language lang)
{
switch (lang)
{case
language.english:
Englishgreeting (name);
break;
Case Language.chinese:
chinesegreeting (name);
break;
}
}
OK, although this solves the problem, but I do not say it is easy to think that this solution is very poor scalability, if we need to add Korean version, Japanese version, we have to repeatedly modify the enumeration and Greetpeople () method to adapt to new requirements.
Before considering a new solution, let's look at the Greetpeople method signature:
Public void Greetpeople (string name, Language lang);
We look only at string name, where string is the parameter type, and name is a parameter variable, which represents the value of "Liker" when we assign it to the name string "Liker", and when we assign it "Li Zhizhong", it represents the value "Li Zhizhong". Then, we can do other things with this name in the body of the method. Hey, this is nonsense, just learn the procedure to know.
If you think again, if the Greetpeople () method can accept a parameter variable, this variable can represent another method, when we give the variable englishgreeting, it represents the Englsihgreeting () method When we assign a value to Chinesegreeting, it represents the Chinesegreeting () method. We named this parameter variable makegreeting, so it is not possible to assign a value to this makegreeting parameter when invoking the Greetpeople () method, just as you would for name assignment (chinesegreeting or englsihgreeting, etc.). We can then use makegreeting in the method body, as well as with other parameters. However, since makegreeting represents a method, it should be used in the same way that it is assigned (such as chinesegreeting), for example: makegreeting (name);
Well, with the idea, we're going to change the Greetpeople () method now, so it should be like this:
public void Greetpeople (string name, * * * makegreeting)
{
makegreeting (name);
}
NOTE * * *, this position is usually placed in the type of parameters, but so far, we just think that there should be a way to represent the parameters, and to rewrite the Greetpeople method in this way, now there is a big problem: this represents the method of makegreeting What type of argument should be.
Description: It is no longer necessary to enumerate, because dynamically deciding which method to use when assigning values to makegreeting is chinesegreeting or englishgreeting, and within the two methods, the use of the Good Morning "or" Good Morning "made a distinction.
Smart you should have thought of it, now is the time to delegate, but before we tell the delegates, let's look at the signatures of the chinesegreeting () and englishgreeting () methods that the makegreeting parameter can represent:
Public void Englishgreeting (string name)
Public void Chinesegreeting (string name)
As name can accept String type "true" and "1", but cannot accept a bool type of true and type 11 of int. The makegreeting parameter type definition should be able to determine the type of method that makegreeting can represent, and further, the parameter type and return type of the method that makegreeting can represent.
Thus, the delegate appears: it defines the kind of method that the makegreeting parameter can represent, namely the type of the makegreeting parameter.
The definition of the delegate in this example:
Public delegate void Greetingdelegate (string name);
Compared with the signature above englishgreeting () method, the rest is not exactly the same except for adding the delegate keyword. Now, let's Change the Greetpeople () method again, as follows:
public delegate void Greetingdelegate (string name);
public void Greetpeople (string name, Greetingdelegate makegreeting)
{
makegreeting (name);
}
As you can see, the delegate greetingdelegate appears in the same position as string, and string is a type, then greetingdelegate should also be a type, or class. But the way the delegate is declared is completely different from the class. In fact, delegates are actually compiled into classes when they are compiled. Because Delegate is a class, you can declare a delegate in any place where you can declare a class. More content will be covered below, now, take a look at the complete code for this example:
public delegate void Greetingdelegate (string name);
Class
Program {
private static void Englishgreeting (string name)
{
Console.WriteLine ("Good Morning," + name);
}
private static void Chinesegreeting (string name)
{
Console.WriteLine ("Good Morning," + name);
}
private static void Greetpeople (string name, Greetingdelegate makegreeting)
{
makegreeting (name);
}
static void Main (string[] args)
{
greetpeople ("Liker", englishgreeting);
Greetpeople ("Li Zhizhong", chinesegreeting);
Console.ReadLine ();
}
We now make a summary of the delegate: The delegate is a class that defines the type of the method so that it can be passed as a parameter to another method, which dynamically assigns the method to the parameter, avoiding the extensive use of if in the program ... Else (Switch) statement, while making the program more extensible.
1.1.2 Bind a method to a delegate
See here, is not a little bit of a wake-up feeling. So, are you thinking: In the above example, I don't have to assign a value directly to the name parameter in the Greetpeople () method, and I can use variables like this:
static void Main (string[] args)
{
greetpeople ("Liker", englishgreeting);
Greetpeople ("Li Zhizhong", chinesegreeting);
Console.ReadLine ();
}
And since the delegate greetingdelegate is the same as the type string, it defines a parameter type, so I can use the delegate as well.