Delegate and event, delegate event
First, the role of delegation is to pass methods of other classes to class methods without class instantiation. Second, the delegate serves as a bridge between the event and the method to respond to the event (that is, the method to respond to the event is passed to the event ). It should be noted that the delegation and class are at the same level, and the events and methods are at the same level.
Full text
Events and delegation seem to be hard to understand, because their usage is very different from common encodings. For example, we usually write Synchronous Code and call a type of method, the result of method execution is displayed immediately, which is logical. However, in some cases, the Synchronous Code may not meet the requirements. Take the bus for example, if the Traffic Control Center wants each bus to send a signal to itself when arriving at a site so that they can know the traffic conditions at any time, and use the Synchronous Code, the public steam object must certainly call the control center object, in this case, two types are closely coupled. Since other types need to respond to their own behaviors, it seems inevitable to call methods of their types in person. In synchronous code, it is difficult to avoid this close type call relationship. The other difference is that in general, we only pass attributes as parameters to methods, but seldom consider passing one method to another method. We discard the difficult concepts of events and delegation in various C # reference books, and imagine a scenario to understand the use of events and delegation: an IT company, the chairman does not want his employees to play games during work hours, but may not stare at every employee all the time. Therefore, he wants to use a new method to monitor employees: if an employee violates regulations, a device or a specialized invigilator will automatically send a message to him, and the chairman of the board only needs to handle the incident. Therefore, this use case is actually an interaction between the Chairman and employee. The following code shows you how to use the delegate and event mechanism to implement this interaction: first, we need to define a delegate type between the chairman class and the employee class to transfer events between the two. This type is a monitoring device or an invigilator responsible for reporting small reports:
- Public delegate void DelegateClassHandle ();
The process of defining a delegate is similar to the definition of a method, but it does not have a method body. To define a delegate, you must add the keyword delegate. Since the definition delegate is actually quite a class, you can define the delegate anywhere in the definition class. In addition, you can add general access modifiers such as public, private, and protected based on the delegate visibility. The Return Value Type of a delegate is void, which does not indicate that the delegate type has a return value. The return value type refers to the target function type of the delegate, that is, the return value of an event processing function entrusted by the delegate is void. The code for creating an Employee class is as follows:
- Public class Employee
- {
- Public event DelegateClassHandle PlayGame;
- Public void Games ()
- {
- If (PlayGame! = Null)
- {
- PlayGame ();
- }
- }
- }
The Employee class Employee code defines a DelegateClassHandle-type event PlayGame, which is also defined in a special way. First, you must use the keyword event to indicate that PlayGame is an event, at the same time, you must declare that the delegate type of this event is DelegateClassHandle. The delegate object of this type will be responsible for notifying the event. If an employee starts playing a game, it will execute the Games method. Once this method is called, an event PlayGame will be triggered, then the Chairman will receive a message about the event-someone is playing a game. The Chairman class code is as follows. He has a method named Notify y to receive messages:
- Public class Admin
- {
- Public void Policy ()
- {
- System. Console. WriteLine ("someone is playing game ");
- }
- }
How can I associate the PlayGame event of Employee ee with the Notify method of Admin? You only need to bind events. The specific process is as follows:
- Employee employee = new Employee ();
- Admin admin = new Admin ();
- Employee. PlayGame + = new DelegateClassHandle (admin. Policy );
- Employee. Games ();
Pay attention to the code bound to the event:
- Employee. PlayGame + = new DelegateClassHandle (admin. Policy );
Use DelegateClassHandle to bind the interaction between the two classes. after the Games method is called, the PlayGame event is triggered, and the event will be delegated to the Notify method of admin for handling, notifying the chairman of the board of directors that an employee plays the game during work hours. However, the chairman of the board is not satisfied with this simple notification. He also wants to know who violates the regulations during work hours. Obviously, the required parameters must be passed to the delegate object, which can be easily implemented. The event parameters can be set to any type of data. In the. NET Framework, the event parameter base class EventArgs is also provided for passing event data. A Custom Event parameter class CustomeEventArgs is derived from the EventArgs class, which carries the employee name and age information:
- Public class CustomeEvetnArgs: EventArgs
- {
- String name = "";
- Int age = 0;
- Public CustomeEvetnArgs ()
- {}
- Publicstring Name
- {
- Get {returnthis. name ;}
- Set {this. name = value ;}
- }
- Publicint Age
- {
- Get {returnthis. age ;}
- Set {this. age = value ;}
- }
- }
Modify the definition of the delegate type DelegateClassHandle so that it carries the necessary parameter: public delegate void DelegateClassHandle (object sender, CustomeEvetnArgs e); the employee class code is modified as follows:
- Public class Employee
- {
- Private string _ name;
- Public string Name
- {
- Get {return _ name ;}
- Set {_ name = value ;}
- }
- Private int _ age;
- Public int Age
- {
- Get {return _ age ;}
- Set {_ age = value ;}
- }
- Public event DelegateClassHandle PlayGame;
- Public void Games ()
- {
- If (PlayGame! = Null)
- {
- CustomeEvetnArgs e = new CustomeEvetnArgs ();
- E. Name = this. _ name;
- E. Age = this. _ age;
- PlayGame (this, e );
- }
- }
- }
In the Games method, create a CustomeEventArgs object, and set the required attributes Name and Age. The Chairman's notice method must also be modified accordingly:
- Public class Admin
- {
- Public void Policy (object sender, CustomeEvetnArgs e)
- {
- System. Console. WriteLine (e. Name + "is" + e. Age. ToString ());
- }
- }
The code for associating two types of objects also needs to be modified accordingly:
- Employee employee = new Employee ();
- Employee. Name = "Mike ";
- Employee. Age = 25;
- Admin admin = new Admin ();
- Employee. PlayGame + = new DelegateClassHandle (admin. Policy );
- Employee. Games ();
After the modified Code is run, when Mike calls the Games method to play the game, the PlayGame event is automatically triggered, and the event carries the relevant information to notify admin, the latter's Notify y method will receive the data and output "Mike is 25", telling the Chairman that Mike is 25 years old and is playing games during work hours. A delegate can be a multi-channel broadcast (Mulitcast), that is, an event can be delegated to multiple objects for receiving and processing. In the preceding example, if another manager has the same preferences as the chairman of the board, the delegate can notify the employee of the PlayGame event. First, define the manager class:
- Public class Manager
- {
- Public void Policy (object sender, CustomeEvetnArgs e)
- {
- System. Console. WriteLine (sender. ToString () + "-" + e. Name );
- }
- }
The Notify method of the Manager type is the same as that of the Admin type, and the corresponding information is also received. The bind method of the delegate multicast is still using the + = Operator. The method is shown in the following code:
- Employee employee = new Employee ();
- Employee. Name = "Mike ";
- Employee. Age = 25;
- Admin admin = new Admin ();
- Manager manager = new Manager ();
- Employee. PlayGame + = new DelegateClassHandle (admin. Policy );
- Employee. PlayGame + = new DelegateClassHandle (manager. Policy );
- Employee. Games ();
When this method is executed, the reader will see that the Notify y method of admin and manager will be notified and called for execution. In this way, both the Chairman and manager will know that Mike is playing the game. If the Chairman does not want the manager to receive this notification, how can he unbind PlayGame from the manager event? It is also very simple. Run the following statement before the employee. Games method is called:
- Employee. PlayGame-= new DelegateClassHandle (manager. Policy );
Finally, we should remind readers that the Games method in the Employee class should determine whether the event is null before triggering the event PlayGame. When the Games method of the employee object triggers the event PlayGame, a target function must be provided to handle the event, and the statement determines whether the target function exists. If the game method is called directly without binding the event, an NullReferenceException occurs in the event PlayGame. Can the reader draw any conclusions from the delegate and Event code? There are two types that need to have a call relationship, but no actual call code is written in their respective implementations. They only complete the message transmission process through an event and a third-party delegate type. There is no close coupling between the two types. They seem to communicate loose through a delegate object, realizing the "high aggregation" and "low coupling" ideas that have been promoted in this book.
Category: C # classroom