Reprint: Delegate in C #

Source: Internet
Author: User

Original address http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx thank Bo Master share!

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 an example of what a delegate is, why I want to use a delegate, and also a discussion of their intermediate code.

To 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, here slightly     Englishgreeting (name);}  Public void Englishgreeting (string  name) {    Console.WriteLine ("" + 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 ("" + 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 something extra, like initialize and so on, here a little   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?

Note: It is no longer necessary to enumerate here, because when assigning a value to makegreeting, we 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)publicvoid 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.

Note: 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:

usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceDelegate {//defines the delegate, which defines the type of method that can be represented      Public Delegate voidGreetingdelegate (stringname); classProgram {Private Static voidEnglishgreeting (stringname) {Console.WriteLine ("Morning,"+name); }           Private Static voidChinesegreeting (stringname) {Console.WriteLine ("Good Morning,"+name); }           //Note This method, which accepts a method of type Greetingdelegate as a parameter           Private Static voidGreetpeople (stringname, Greetingdelegate makegreeting)            {makegreeting (name); }           Static voidMain (string[] args) {Greetpeople ("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.

To bind 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;     " Jimmy Zhang " ;     " 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;     = englishgreeting;     = 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;     // assign a value to a variable of the delegate type first    Delegate1 + = chinesegreeting;   // to bind a method     to this delegate variable // the Englishgreeting and Chinesegreeting methods    will be called successively 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;     // assign a value to a variable of the delegate type first    Delegate1 + = chinesegreeting;   // to bind a method    to this delegate variable // the Englishgreeting and Chinesegreeting methods    will be called successively Delegate1 ("Jimmy Zhang");       Console.readkey ();}

Note: This is not a problem in this case, but looking back at the definition of greetpeople () above, in it can do some work for englshihgreeting and chinesegreeting, for the sake of simplicity I did omitted.

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:

New+ = chinesegreeting;   // to 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:

New+ = englishgreeting;   // this time with the "+ =", binding syntax. delegate1 + = chinesegreeting;   // to 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 voidMain (string[] args) {greetingdelegate delegate1=Newgreetingdelegate (englishgreeting); Delegate1+ = chinesegreeting;//to bind a method to this delegate variable//the Englishgreeting and Chinesegreeting methods will be called successivelyGreetpeople ("Jimmy Zhang", delegate1);    Console.WriteLine (); Delegate1-= englishgreeting;//to unbind a englishgreeting method//will only call chinesegreetingGreetpeople ("Zhang Ziyang", delegate1); Console.readkey ();}

The output is:
Morning, Jimmy Zhang
Good morning, Jimmy Zhang.
Good morning, Zhang Ziyang.

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.

Reprint: Delegate in C #

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.