Use delegation in the following cases:
When the event design mode is used.
When static methods are encapsulated.
When the caller does not need to access other attributes, methods, or interfaces in the objects that implement the method.
A convenient combination.
When the class may require multiple implementations of this method.
Use the interface in the following cases:
When there is a set of methods that may be called.
When the class only needs a single implementation of the method.
When the class using the interface wants to forcibly convert the interface to another interface or class type.
When the implemented method is linked to the type or identifier of the class: for example, compare the method.
Code
Public class person
{
Public Delegate void personworkhandle (string MSG );
Public event personworkhandle workend;
Public void dowork ()
{
Workend ("My work has been completed in person ");
}
}
Public class person1
{
Public Delegate void personworkhandle (string MSG );
Private personworkhandle workend;
Public void add_workend (personworkhandle value)
{
Workend + = value;
}
Public void remove_workend (personworkhandle value)
{
Workend-= value;
}
Public void dowork ()
{
Workend ("My work has been completed in person1 ");
}
}
Class Program
{
Static void main (string [] ARGs)
{
// Directly use the event
Person P = new person ();
P. workend + = workendhandle;
P. dowork ();
// Delegate a Simulated Event
Person1 p1 = new person1 ();
P1.add _ workend (workendhandle );
P1.dowork ();
Console. Readline ();
}
Static void workendhandle (string MSG)
{
Console. writeline (MSG );
}
}
Many books like to describe the Commission and event at a high level, which leads to doubts about the relationship between the two, and the Commission and event seem to be no different.
In fact, the event in. NET is the syntactic sugar that Microsoft provides to me. The purpose is to reduce the amount of code. In fact, all the functions related to the event can be implemented by delegation.
In person, a trigger event is used to notify the caller. After my work is done, workend is an event.
In person1, events are useless. Purely delegate methods completely achieve the purpose of events.
If you use the Il disassembly program to view the generated code, you will find that the code in my person and person1 is similar.
In fact, my person1 simulates the delegate code automatically generated by CLR. When you see the workend event in person, private variable delegate is automatically generated during compilation, and add _ remove _
Code written using events reduces the amount of code. This is an example.
Code
Private personworkhandle workend;
Public void add_workend (personworkhandle value)
{
Workend + = value;
}
Public void remove_workend (personworkhandle value)
{
Workend-= value;
}
Use one sentence
Public event personworkhandle workend;
Can replace
In addition, you can easily use the + = Operator when registering an event handler.
In short, events are a special application of delegation. There is nothing mysterious about them.
Method signature:
A Method signature consists of a method name and a parameter list (the order and type of parameters.
Note: The method signature does not include the return value of the method. Although each overload method can have different return types, a single return type is not enough to distinguish which method is used.
In C #, two or more methods in the same class can have different names, as long as their parameter declarations are different. In this case, this method is called overload. This process is called method overloading ). Method Overloading is one of the most useful features of C.
When a method is called, C # uses the method signature to determine which method to call. Therefore, the parameter list of each overload method must be different. Although each overload method can have different return types, a single return type is not enough to distinguish which method is used. When C # Calls an overloaded method, the method that matches the parameters of the parameter is executed.
An example in reality:
Mr. Wang commissioned Mr. Zhang to help him monitor Mr. Li and beat him as long as he danced. Well, I will use this example to describe the delegate in C #. There are three classes now, haha, it's Xiao Wang, Xiao Zhang, and Xiao Li. Then Mr. Zhang is the delegate.
The following example
Public class Xiao Li
{
Public Xiao Li (Xiao Zhang OBJ)
{
// Constructor, passing in the example of a small image
}
// The following is Xiao Li's dancing Method
Public void dancing ()
{
// Dancing Method
Pass this method to John
Instance snapshot (this );
}
}
Let's define the delegate Mr. Zhang.
// Define parameters and pass Xiao Li in. The following object is actually an example of Xiao Li.
Public Delegate (Object sender );
The following is a definition of John, who won't do anything else, but beat people. :-)
Public class Wang
{
Public Wang
{
// Constructor
}
// Tips
Public void (Object OBJ) // The OBJ parameter is the object to be played.
{
// I typed. I typed it !!
}
}
The following are scenarios:
Public class ballroom
{
Public int main ()
{
New instance Mr. Wang;
New instance Xiao Zhang (Xiao Wang. Da );
\ This sentence is Xiao Wang commissioned Xiao Zhang to monitor Xiao Li
New instance Xiao Li (Xiao Zhang );
Example: Xiao Li dancing;
// Xiao Li will be beaten when dancing. :-)
}
}
For example, in a company (scenario), you are the boss and have two employees, Xiao Zhang and Xiao Li. You command Xiao Zhang to pay attention to Xiao Li. If you play games online during software development, you will record it and deduct 100 yuan from Xiao Li's salary. This is actually a delegate in reality.
Now we provide a code, C # console program, compiled and run through
Using system;
Namespace csharpconsole
{
Public class scenario
{
[Stathread]
Public static void main (string [] ARGs)
{
Console. writeline ("the scenario has started ....");
// Generate Tom
Wang W = new Wang ();
// Generate a small account
John Z = new John ();
// Specify monitoring
Z. playgame + = new playgamehandler (W. Deduction );
// Start playing the game
Z. Play the game ();
Console. writeline ("End of scenario ...");
Console. Readline ();
}
}
// The person responsible for fee deduction
Public class Wang
{
Public Wang ()
{
Console. writeline ("generate Tom ...");
}
Public void deduction (Object sender, eventargs E)
{
Console. writeline ("Mr. Wang: Good boy, dare to play games during work hours ...");
Console. writeline ("JOHN: look at how much your kid has ...");
John f = (John) sender;
Console. writeline ("John's money:" + F. Qian. tostring ());
Console. writeline ("start to deduct money ......");
System. Threading. thread. Sleep (500 );
F. Money = f. Money-500;
Console. writeline ("the button is finished... Now, James is still there:" + F. Qian. tostring ());
}
}
// If the game is played, an event is triggered.
Public class Xiao Zhang
{
// Define an event first, which means "Xiao Zhang" is playing the game.
Public event playgamehandler playgame;
// Save the small money variable
Private int m_money;
Public Xiaozhang ()
{
Console. writeline ("generating images ....");
M_money = 1000; // constructor, which initializes the small Zhang's money.
}
Public int money // This property can be used to operate on the small Zhang's money.
{
Get
{
Return m_money;
}
Set
{
M_money = value;
}
}
Public void ()
{
Console. writeline ("John started playing the game .....");
Console. writeline ("Xiao Zhang: CS fun, hahaha! I play .....");
System. Threading. thread. Sleep (500 );
System. eventargs E = new eventargs ();
Onplaygame (E );
}
Protected virtual void onplaygame (eventargs E)
{
If (playgame! = NULL)
{
Playgame (this, e );
}
}
}
// Define the delegate Handler
Public Delegate void playgamehandler (Object sender, system. eventargs E );
}
Introduction
Delegation and events are widely used in. NET Framework. However, it is not easy for many people who have been in contact with C # for a long time to better understand delegation and events. They are like a hacker. People who have passed the hacker think it is too easy, and people who have never seen the delegate and event will feel different (BI) panic and uncomfortable. In this article, I will use two examples to explain from a simple perspective what is delegation, why is delegation used, how events come from, and why ,. the significance of delegation, events, delegation, and events in the Net Framework to the observer design pattern, and their intermediate code is also discussed.
Use a method as a method parameter
Let's look at the two simplest methods, no matter how the title is spoken or whether the delegate is actually something. They are just a greeting on the screen:
Public void greetpeople (string name ){
// Do some additional things, such as initialization.
Englishgreeting (name );
}
Public void englishgreeting (string name ){
Console. writeline ("Morning," + name );
}
For the moment, no matter whether the two methods have any practical significance. Greetpeople is used to say hello to someone. When we pass the name parameter representing someone's name, such as "Jimmy", In this method, the englishgreeting method will be called and the name parameter will be passed again, englishgreeting is used to output "Morning, Jimmy" to the screen ".
Now let's assume that this program needs to be global. Oh, no. I am a Chinese. I don't understand what "Morning" means. What should I do? Okay, let's add a Chinese edition greeting method:
Public void chinesegreeting (string name ){
Console. writeline ("good morning," + name );
}
At this time, greetpeople also needs to be changed. Otherwise, how can we determine which version of greeting method is suitable? Before proceeding, we 'd better define another enumeration as the basis for judgment:
Public Enum language {
English, Chinese
}
Public void greetpeople (string name, language Lang ){
// Do some additional things, such as initialization.
Swith (Lang ){
Case language. English:
Englishgreeting (name );
Break;
Case language. Chinese:
Chinesegreeting (name );
Break;
}
}
Okay, even though this solves the problem, it is easy to think of without saying that this solution has poor scalability. If we need to add Korean and Japanese Versions later, you have to modify the enumeration and greetpeople () methods repeatedly to meet new requirements.
Before considering a new solution, let's look at the greetpeople method signature:
Public void greetpeople (string name, language Lang)
Let's just look at the string name. Here, string is a parameter type, and name is a parameter variable. When we assign the name string "Jimmy", it represents the value of "Jimmy; when we grant it "Zhang Ziyang", it also represents the value of "Zhang Ziyang. Then, we can perform other operations on this name in the method body. Ah, is this nonsense? I knew it when I first learned the program.
If you think about it again, if the greetpeople () method can accept a parameter variable, this variable can represent another method. When we assign englishgreeting to this variable, it represents englsihgreeting () this method. When we assign chinesegreeting to it, it also represents the chinesegreeting () method. We name this parameter variable makegreeting, so it is not the same as when we assign a value to the name. When we call the greetpeople () method, is this makegreeting parameter also assigned a value (chinesegreeting or englsihgreeting )? Then, we can use makegreeting in the method body just like using other parameters. However, because makegreeting represents a method, it should be used in the same way as the method it is assigned (such as chinesegreeting), for example:
Makegreeting (name );
Now that we have the idea, let's change the greetpeople () method. It should look like this:
Public void greetpeople (string name, *** makegreeting ){
Makegreeting (name );
}
Note that ***, this location should usually be placed in the parameter type, but so far, we just thought that there should be a parameter that can represent the method, and rewrite the greetpeople method according to this idea. Now there is a big problem:This indicates the makegreeting parameter of the method.?
Note: Enumeration is no longer needed here, because when assigning values to makegreeting, you dynamically decide which method to use, whether it is chinesegreeting or englishgreeting. Inside these two methods, we have already made a distinction between "Morning" and "good morning.
You should have thought about it. Now it's time to delegate the game, but let's look at the chinesegreeting () and englishgreeting () parameters that can be represented by the delegate () method signature:
Public void englishgreeting (string name)
Public void chinesegreeting (string name)
As if the name can accept "true" and "1" of the string type, but cannot accept the same true of the bool type and 1 of the int type. The parameter Type Definition of makegreeting should be able to determine the types of methods that makegreeting can represent. Further, it is the parameter type and Reverse type of the methods that makegreeting can represent. Therefore, the delegate appears: it defines the types of methods that can be represented by the makegreeting parameter, that is, the type of the makegreeting parameter.
Note: If the above sentence is a detour, I will translate it into this: String defines the type of the value that the name parameter can represent, that is, the type of the name parameter.
Definition of delegation in this example:
Public Delegate void greetingdelegate (string name );
Can I compare it with the signature of the above englishgreeting () method? Except for the delegate keyword, are the rest identical?
Now let's change the greetpeople () method again, as shown below:
Public void greetpeople (string name, greetingdelegate makegreeting ){
Makegreeting (name );
}
As you can see, the position of the delegate greetingdelegate is the same as that of the string, and the string is a type, so greetingdelegate should also be a type or class ). However, the delegate declaration method is completely different from the class. What is this? In fact, the Delegate will indeed be compiled into classes during compilation. Because delegate is a class, delegates can be declared wherever classes can be declared. For more information, see the complete code of this example:
Using system;
Using system. Collections. Generic;
Using system. text;
Namespace delegate {
// Define the delegate, which defines the types of methods that can be represented
Public Delegate void greetingdelegate (string name );
Class program {
Private Static void englishgreeting (string name ){
Console. writeline ("Morning," + name );
}
Private Static void chinesegreeting (string name ){
Console. writeline ("good morning," + name );
}
// Note that this method accepts a greetingdelegate method as a parameter.
Private Static void greetpeople (string name, greetingdelegate makegreeting ){
Makegreeting (name );
}
Static void main (string [] ARGs ){
Greetpeople ("Jimmy Zhang", englishgreeting );
Greetpeople ("Zhang Ziyang", chinesegreeting );
Console. readkey ();
}
}
}
The output is as follows:
Morning, Jimmy Zhang
Good morning, Zhang Ziyang
Let's make a summary of the delegation.:
A delegate is a class that defines the type of a method so that the method can be passed as a parameter of another method. This way, the method is dynamically assigned to the parameter, it can avoid using the IF-else (switch) statement in a large number in the program, and make the program more scalable.