The delegation and events of C # Learning Series

Source: Internet
Author: User

1. Introduction

Delegates and events are widely used in the. Net framework, however, a good understanding of delegates and events is not easy for many people who are not in touch with C # for a long time. They are like a sill, the person who passed the threshold, think it is too easy, and not the past people every time to see the Commission and events feel the heart Don't (Biè) panic, mixed body uncomfortable. In this article, I'll go through two examples of what is a delegate, why I use delegates, the origins of events, the meanings of delegates and events in the. Net framework, delegates, and events to the observer design pattern, and also a discussion of their intermediate code.

2. Use a method as a parameter to a method

Let's take a look at the following two simplest methods, regardless of how the title is wrapped or what the delegate is, and they are simply outputting a word of greeting on the screen:

Public void greetpeople (string name) { //do some extra things, such as initialization, and so on, slightly englishgreeting (name);} public void englishgreeting (string name) {Console.WriteLine ("morning," + name);}

Regardless of whether these two methods have any practical significance. Greetpeople used to say hello to someone when we pass the name parameter that represents someone's name, say "Jimmy," and in this method, the Englishgreeting method is called, passing the name parameter again, The englishgreeting is used to output "morning, Jimmy" to the screen.

Now suppose this program needs globalization, oops, no, I am Chinese, I do not understand what "morning" means, how to do it? OK, we'll add a Chinese version of the greeting method:

Public void chinesegreeting (string name) {Console.WriteLine ("Good morning," + name);}

At this time, Greetpeople also need to change a change, otherwise how to determine which version of the greeting greeting method appropriate? Before we do this, we'd better define an enumeration as the basis for judgment:

Public enum language{中文版, Chinese} public void greetpeople (string name, Language lang) { //do a Some additional things, such as initialization and so on, here are slightly swith (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 the solution is very poor scalability, if we need to add the Korean version, Japanese version, we have to repeatedly modify the enumeration and Greetpeople () method to adapt to the new requirements.

Before considering a new solution, let's take a look at Greetpeople's method signature:

Public void greetpeople (string name, Language lang)

We only look at string name, where string is the parameter type, name is a parameter variable, and when we assign the name string "Jimmy" it represents the value of "Jimmy", and when we assign it "Zhang Ziyang" it represents the value of "Zhang Ziyang". We can then perform other operations on the name within the method body. Hey, this is nonsense, just learn the program will know.

If you think about it again, if the Greetpeople () method can accept a parameter variable, this variable can represent another method, and when we assign a value englishgreeting to the variable, it represents the Englsihgreeting () method When we assign a value to Chinesegreeting, it represents the Chinesegreeting () method. We name this parameter variable makegreeting, so it is not possible to assign a value to this makegreeting parameter when calling the Greetpeople () method, as in assigning a value to name ( Chinesegreeting or englsihgreeting, etc.)? We can then use makegreeting in the body of the method, 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), such as:

Makegreeting (name);

Well, with the idea, we're now going to change the Greetpeople () method, then it should look like this:

Public void greetpeople (string name, * * * makegreeting) {makegreeting (name);}

Note that this position is usually placed in the type of parameter, but so far, we just think that there should be a parameter that can represent the method, and according to this idea to rewrite the Greetpeople method, now there is a big problem: What type of makegreeting parameter should be used to represent the method?

Tip: It is no longer necessary to enumerate, because when assigning to makegreeting dynamically decide which method to use, whether it is chinesegreeting or englishgreeting, and within this two method, the use of " Morning "or" Good Morning "made a distinction.

Smart you should have thought, now is the time to entrust the appearance, but before the delegation, we look at the makegreeting parameter can represent the chinesegreeting () and the Englishgreeting () method signature:

Public void englishgreeting (string name) public void chinesegreeting (string name)

As name can accept the string type "true" and "1", but cannot accept the bool type of true and int type 11. the makegreeting parameter type definition should be able to determine the kind of method that makegreeting can represent, and further, that is, 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, that is, the type of the makegreeting parameter.

Tip: If the above is a bit of a detour, I translate it to this: string defines the kind of value that the name parameter can represent, that is, the type of the name parameter.

The definition of a delegate in this example:

Public delegate void greetingdelegate (string name);

Can you compare the signature of the Englishgreeting () method above, except that the delegate keyword is added, the rest is not exactly the same?

Now, let's Change the Greetpeople () method again, as follows:

Public void greetpeople (string name, Greetingdelegate makegreeting) {makegreeting (name);}

As you can see, the delegate greetingdelegate appears in the same position as the string, and the string is a type, then the greetingdelegate should also be a type, or class. But the way the delegate is declared and the class is completely different, what's the matter? In fact, a delegate compiles into a class when it is compiled. Because delegate is a class, you can declare a delegate anywhere you can declare a class. More content will be described below, now, take a look at the complete code for this example:

Using System;Using System.Collections.Generic;Using System.Text;NamespaceDelegate {Defines the delegate, which defines the type of method that can be representedPublicDelegatevoidGreetingdelegate (string name);Classprogram {PrivateStaticvoidEnglishgreeting (String name) {Console.WriteLine ("Morning," + name);}PrivateStaticvoidChinesegreeting (string name) {Console.WriteLine ( "Good morning," + name);} //Note this method, which accepts a greetingdelegate type method as a parameter private static void greetpeople (string name, GreetingDelegate makegreeting) {makegreeting (name);} static void main (string[] args) {GreetPeople ( Span class= "hljs-string" > "Jimmy Zhang", englishgreeting); Greetpeople ( "Zhang Ziyang", chinesegreeting); Console.readkey (); }}} The output is as follows: Morning, Jimmy Zhang Good morning, Zhang Ziyang

We now make a summary of the Commission:

A delegate is a class that defines a method's type so that it can be passed as a parameter to another method, which dynamically assigns the method to the parameter, avoids the large use of the If-else (Switch) statement in the program, and makes the program more extensible.

3. Binding a method to a delegate

See here, is there so little rude awakening feeling? So, are you thinking: In the example above, I don't necessarily have to assign a value to the name parameter directly in the Greetpeople () method, I can use a variable like this:

static void Main (string[] args) { string name1, name2; name1 = "Jimmy Zhang"; name2 = "Zhang Ziyang"; Greetpeople (name1, englishgreeting); Greetpeople (name2, chinesegreeting); Console.readkey (); }

And since the delegate greetingdelegate has the same status as the type string, it defines a parameter type, so can I use the delegate as well?

static void Main (string[] args) {greetingdelegate delegate1, delegate2; delegate1 = englishgreeting; delegat e2 = chinesegreeting; Greetpeople ("Jimmy Zhang", delegate1); Greetpeople ("Zhang Ziyang", delegate2); Console.readkey (); }

As you might expect, this is no problem and the program outputs as expected. What I want to say here is that the delegate is different from a string: You can assign multiple methods to the same delegate, or bind multiple methods to the same delegate, and call the delegate in turn, calling the method to which it is bound. In this example, the syntax is as follows:

static void Main (string[] args) {greetingdelegate delegate1; delegate1 = englishgreeting; //Assign the variable of the delegate type delegate1 + = chinesegreeting; // give this delegate variable a method of binding again //Will call Englishgreeting and Chinesegreeting method Greetpeople ("Jimmy Zhang", delegate1); Console.readkey (); The output is: Morning, Jimmy Zhang Good Morning, Jimmy Zhang

In fact, we can also bypass the Greetpeople method and directly invoke Englishgreeting and chinesegreeting through delegates:

static void Main (string[] args) {greetingdelegate delegate1; delegate1 = englishgreeting; //Assign the variable of the delegate type delegate1 + = chinesegreeting; // give this delegate variable a method of binding again //Will call Englishgreeting and Chinesegreeting method Delegate1 ("Jimmy Zhang"); Console.readkey (); }

Note: This is not a problem in this case, but looking back at the definition of greetpeople () above, it is possible to do some work for englshihgreeting and Chinesegreeting, I made the omission for the sake of simplicity.

Note here that the first use of "=" is the assignment of the syntax, the second time, with the "+ =", is the binding syntax. If you use "+ =" for the first time, a compilation error "Using Unassigned local variables" appears.

We can also use the following code to simplify this process:

Greetingdelegate delegate1 = new Greetingdelegate (englishgreeting); delegate1 + = chinesegreeting; //Bind a method to this delegate variable

See here, it should be noted that the first statement of this code and instantiation of a class is how similar, you can not help but think: the first time you bind a delegate can not use the "+ =" Compilation error, you may use this method to avoid:

Greetingdelegate delegate1 = new Greetingdelegate (); delegate1 + = englishgreeting; //This time with "+ =", binding syntax. Delegate1 + = chinesegreeting; //Bind a method to this delegate variable

In practice, however, there is a compile error: the "Greetingdelegate" method does not take an overload of the "0" parameter. Although the result is a bit frustrating for us, the compilation hint: "Overloads without 0 arguments" again reminds us of the constructor of the class. I know you can't restrain yourself from trying to find out, but before we do, we need to introduce the basics and applications.

Since a delegate can be bound to a method, there should also be a way to remove the binding method, it is easy to think of this syntax is "-=":

static void main ( string[] args) {greetingdelegate delegate1 = new greetingdelegate (englishgreeting); Delegate1 + = chinesegreeting; //to bind this delegate variable again a method //will successively call Englishgreeting and Chinesegreeting method Greetpeople ( "Jimmy Zhang", delegate1); Console.WriteLine (); Delegate1-= englishgreeting; //cancels the binding of Englishgreeting method //will only call chinesegreeting Greetpeople ( "Zhang Ziyang", delegate1); Console.readkey (); The output is: Morning, Jimmy Zhang Good morning, Jimmy Zhang Good Morning, Zhang Ziyang span>

Let's make a summary of the Commission again:

Using delegates, you can bind multiple methods to the same delegate variable, and when you call this variable (the word "call" is used here because the variable represents a method), you can call all the bound methods in turn.

The delegation and events of C # Learning Series

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.