C # delegation and event details (2)

Source: Internet
Author: User
Bind method to delegate
Do you feel like waking up? So, are you wondering: In the above example, I don't have to assign a value to the name parameter directly in the greetpeople () method. I can use the 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 ();
}
Since the same status of the delegate greetingdelegate and the type string is defined as a parameter type, can I use the delegate as well?
Static void main (string [] ARGs ){
Greetingdelegate delegate1, delegate2;
Delegate1 = englishgreeting;
Delegate2 = chinesegreeting;

Greetpeople ("Jimmy Zhang", delegate1 );
Greetpeople ("Zhang Ziyang", delegate2 );
Console. readkey ();
}
As expected, this is fine, and the program is output as expected. Here, I want to talk about the Delegate Feature different from the string feature: You can assign multiple methods to the same delegate, or bind multiple methods to the same delegate, when this delegate is called, the bound methods are called in sequence. In this example, the syntax is as follows:
Static void main (string [] ARGs ){
Greetingdelegate delegate1;
Delegate1 = englishgreeting; // assign a value to the delegate Type Variable
Delegate1 + = chinesegreeting; // bind the delegate variable to another method.

// The englishgreeting and chinesegreeting methods will be called successively
Greetpeople ("Jimmy Zhang", delegate1 );
Console. readkey ();
}

Output:
Morning, Jimmy Zhang
Good morning, Jimmy Zhang
In fact, we can also bypass the greetpeople method and directly call englishgreeting and chinesegreeting through delegation:
Static void main (string [] ARGs ){
Greetingdelegate delegate1;
Delegate1 = englishgreeting; // assign a value to the delegate Type Variable
Delegate1 + = chinesegreeting; // bind the delegate variable to another method.

// The englishgreeting and chinesegreeting methods will be called successively
Delegate1 ("Jimmy Zhang ");
Console. readkey ();
}

Note:This is no problem in this example, but looking back at the above definition of greetpeople (), we can do some work that needs to be done for both engshihgreeting and chinesegreeting, I omitted it for convenience.
Note that "=" is used for the first time, which is the syntax of value assignment; "+ =" is used for the second time, which is the binding syntax. If "+ =" is used for the first time, the compilation error "using unassigned local variables" will occur.
We can also use the following code to simplify this process:
Greetingdelegate delegate1 = new greetingdelegate (englishgreeting );
Delegate1 + = chinesegreeting; // bind the delegate variable to another method.
As you can see, it should be noted that the first statement of this Code is similar to instantiating a class. You can't help but think that the "+ =" Compilation error cannot be used when the delegate is bound for the first time, this method may be used to avoid:
Greetingdelegate delegate1 = new greetingdelegate ();
Delegate1 + = englishgreeting; // The binding syntax is "+ =.
Delegate1 + = chinesegreeting; // bind the delegate variable to another method.
But in fact, there will be a compilation error: the "greetingdelegate" method does not use the "0" parameter overload. Although this result is a bit frustrating, the compilation prompt "no overload of 0 Parameters" reminds us of the class constructor again. I know that you may not be able to find out what it is, but before that, we need to finish introducing basic knowledge and applications.
Since a delegate can bind a method, there should be a way to unbind the method. It is easy to think that this syntax is "-= ":
Static void main (string [] ARGs ){
Greetingdelegate delegate1 = new greetingdelegate (englishgreeting );
Delegate1 + = chinesegreeting; // bind the delegate variable to another method.

// The englishgreeting and chinesegreeting methods will be called successively
Greetpeople ("Jimmy Zhang", delegate1 );
Console. writeline ();

Delegate1-= englishgreeting; // cancel binding to the englishgreeting Method
// Only chinesegreeting will be called
Greetpeople ("Zhang Ziyang", delegate1 );
Console. readkey ();
}
Output:
Morning, Jimmy Zhang
Good morning, Jimmy Zhang
Good morning, Zhang Ziyang
Let's summarize the delegation again:
You can use a delegate to bind multiple methods to the same delegate variable. When you call this variable (the word "call" is used here because this variable represents a method ), you can call all bound methods in sequence.

Event Origin
Let's continue to think about the above program: The above three methods are defined in the programe class, so as to facilitate understanding. In actual application, greetpeople is usually in a class, chinesegreeting and englishgreeting are in another class. Now you have a preliminary understanding of the delegation. It is time to improve the above example. Suppose we put greetingpeople () in a class called greetingmanager, then the new program should look like this:
Namespace delegate {
// Define the delegate, which defines the types of methods that can be represented
Public Delegate void greetingdelegate (string name );

// New greetingmanager class
Public class greetingmanager {
Public void greetpeople (string name, greetingdelegate makegreeting ){
Makegreeting (name );
}
}

Class program {
Private Static void englishgreeting (string name ){
Console. writeline ("Morning," + name );
}

Private Static void chinesegreeting (string name ){
Console. writeline ("good morning," + name );
}

Static void main (string [] ARGs ){
//......
}
}
}
At this time, if you want to implement the output shown above, the main method should be like this:
Static void main (string [] ARGs ){
Greetingmanager GM = new greetingmanager ();
GM. greetpeople ("Jimmy Zhang", englishgreeting );
GM. greetpeople ("Zhang Ziyang", chinesegreeting );
}
We run this code. Well, there is no problem. The program output as expected:
Morning, Jimmy Zhang
Good morning, Zhang Ziyang
Now, let's assume that we need to use the knowledge learned in the previous section to bind multiple methods to the same delegate variable. What should we do? Let's rewrite the code again:
Static void main (string [] ARGs ){
Greetingmanager GM = new greetingmanager ();
Greetingdelegate delegate1;
Delegate1 = englishgreeting;
Delegate1 + = chinesegreeting;

GM. greetpeople ("Jimmy Zhang", delegate1 );
}

Output:
Morning, Jimmy Zhang
Good morning, Jimmy Zhang
Here, we can't help but think of object-oriented design, which focuses on Object encapsulation. Since we can declare variables of the delegate type (in the above example, It is delegate1 ), why don't we encapsulate this variable in the greetmanager class? Isn't it more convenient to use in the client of this class? Therefore, we rewrite the greetmanager class as follows:
Public class greetingmanager {
// Declare the delegate1 variable in the greetingmanager class
Public greetingdelegate delegate1;

Public void greetpeople (string name, greetingdelegate makegreeting ){
Makegreeting (name );
}
}
Now, we can use this delegate variable as follows:
Static void main (string [] ARGs ){
Greetingmanager GM = new greetingmanager ();
GM. delegate1 = englishgreeting;
GM. delegate1 + = chinesegreeting;

GM. greetpeople ("Jimmy Zhang", GM. delegate1 );
}

Output:
Morning, Jimmy Zhang
Good morning, Jimmy Zhang
Although there is no problem in doing so, we find this statement very strange. When the GM. greetpeople method is called, The delegate1 field of GM is passed again:
GM. greetpeople ("Jimmy Zhang", GM. delegate1 );
In this case, why not modify the greetingmanager class as follows:
Public class greetingmanager {
// Declare the delegate1 variable in the greetingmanager class
Public greetingdelegate delegate1;

Public void greetpeople (string name ){
If (delegate1! = NULL) {// if there is a method to register the delegate variable
Delegate1 (name); // call the method by Delegate
}
}
}
On the client side, the call looks more concise:
Static void main (string [] ARGs ){
Greetingmanager GM = new greetingmanager ();
GM. delegate1 = englishgreeting;
GM. delegate1 + = chinesegreeting;

GM. greetpeople ("Jimmy Zhang"); // note that the delegate1 variable does not need to be passed this time.
}

Output:
Morning, Jimmy Zhang
Good morning, Jimmy Zhang
Although this has achieved our desired results, there are still problems:
Here, there is no difference between delegate1 and the string type variables we usually use. We know that not all fields should be declared as public, the best practice is to make public when public and private when private.
Let's first look at what if delegate1 is declared as private? The result is:This is just funny. Because the purpose of declaring a delegate is to expose it to the client of the class for method registration. If you declare it as private, the client will not be able to see it at all. What is the use of the delegate?
Let's take a look at how to declare delegate1 as public? The result is:On the client side, you can assign values to it at will, which seriously damages the encapsulation of objects.
Finally, "=" is used for registration of the first method, which is the value assignment syntax. to instantiate the method, "+ =" is used for registration of the second method ". However, noWhether it is a value assignment or registration, the methods are bound to the delegate, except that the order of the call is different, there is no difference, isn't it really awkward?
Now let's think about it. If delegate1 is not a delegate type but a string type, what would you do?The answer is to use attributes to encapsulate fields.
As a result, event appears, which encapsulates the variables of the delegate type, so that:In the class, whether you declare it as public or protected, it is always private. Outside the class, register the "+ =" and logout "-=" Access delimiters with the same access delimiters as you used when declaring an event.

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.