I. Profile
1. Delegate:
E.g:
Public Delegate Void PrintHandler (String Str);
The delegate declaration defines a type that is packaged in a set of specific parameters and returns. For static methods, the method of delegate the object package to be called. For example methods, the delegate object simultaneously encapsulates an example and a method on this instance. If you have a delegate object and a set of appropriate parameters, you can call the delegate with these parameters.
2. Use of commissioned:
Using system;
Public Class Myclass
{
Public static void main ()
{
Printstr myprinter = new printstr ();
Printhandler myhandler = null;
MyHandler = New PrintHandler (MyPrinter.callprint); // will receive a link to the method to instantiate the commission
IF (MyHandler! = NULL)
MyHandler ("Hello World!"); // Call delegate, equivalent to the method of anonymous call commission
Console.read ();
}
}
Public Delegate Void PrintHandler (String Str); // Declaration Principal Type
Public Class Printstr
{
Public void callprint (String INPUT)
{
Console.writeLine (Input);
}
}
Use the entrust method in C #:
· Creating the method used by the commission must be consistent with the delegate statement (the parameter list, the return value is consistent)
· Use =, - = to make a link, cancel the link or use the delegate.combine and delegate.remove method to implement the DELEGATE.COMBINE.
· You can use multiplevocationList () to get all the commission in the commission chain using the instance method of MulticastDelegate.
· You can't write a commission that contains OUT parameters
Second, the introduction
"Event" in C # is a method of providing a notification to the customer when some things have occurred during the object.
1, the statement of the event:
The format of the declaration is:
Because the commission is used to declare the event, when the event is declared in the class, you must first declare the entrustment type
(1) Two parameters should be adopted;
(2) The two parameters are: "E" parameters for "object source" parameters and package events of the event source; E "parameters;
(3) The type of "e" parameter should be an Eventargs class or derived from the Eventargs class.
The following definition:
Public Delegate Void PrintHandler (Object Sender, System.EventArgs E);
Then we can declare the incident of the entrusted type
E.g:
Public Event PrintHandler Print; When an event occurs, its client is called to provide a delegation.
2, call the event:
Class declared the event, which can process the event as a field indicated by the delegate type. If no customer will be binded to the event, the field will be empty; otherwise the field reference should be invoked when calling the event. Therefore, when you call an event, you will usually check if it is empty, then call the event. (Calling the event, that is, triggering the event, can only be carried out from the date of claiming the event)
IF (Print! = NULL)
{
Print (this, e);
}
3. Event binding:
From the outside of the class, the event is accessed by a public member of the class, through the class name. Event name form, but can only bind and release the binding operation, without other operations.
Class name. Print = New PrintHandler (Binding method name) // Bind a method to the Print event
Class name. Print - = New PrintHandler (Binding method name) // Releases a method of a binding to the Print event from the print event
Third, the use of entrusted and events
Principal and events are more comparison in user interface programs, such as Button on the user ui in WinForm or WebForm and its Click event:
/ / Bind the button1_click () method to the click control button of Button1
This.Button1.Click = new system.eventhandler (this. Button1_click);
Private Void Button1_Click (Object Sender, System.Eventargs E) // Button1_Click () method
{
......
}
However, in addition to user interface programs, event-driven mode is also used in many other places, such as observer or pubscribe / subside / subside / subside / subside (Publish) a certain one can be triggered Events, while others can subscribe to this event. Once this publisher triggered the event, then the runtime environment will immediately tell all subscriber classes subscribed to the event: this event happens! Thus each subscriber class can make their own reactions (call the corresponding method).
Let's take a practical example in your life to explain how to use entrusted and events, as well as the benefits brought by using commission and events:
For example, there is a company (scene), you are the boss, there are supervisors and employees in the hands, as the boss, you will assign (entrusted) the work of the competent management employee, if an employee plays games, let a supervisor from the employee's salary Ridside 500 yuan.
This is the commission in reality.
In the write program, suppose the programmer is the boss, there are two classes for the supervisors and employees, and the supervisor Xiao Wang and the employee Xiaoshao are two types of object instances. The employee has a method: play the game, and there is an event that plays games. He will inspire this incident in playing games. The supervisor is responsible for handling the event, he is responsible for deducting the salary of the employee of the game 500.
(1) First, let's take a look at a common design method in the case of non-grazing (of course, this is not the only way, not the best way, but very common):
Using system;
Namespace csharpconsole {
Public class scene
{
[Stathread]
Public static void main (string [] args)
{
Console.writeline ("Scene begins.");
// Generate the subject of the supervisor class
Director Xiao Wang = New Director ();
// Generate the object instance of the work class, specify his supervisor
Employee Xiao Zhang = New Employee (Xiao Wang);
Console.writeline ("The employee has a salary:" small sheet. Salary. Tostring ());
// Employee start playing games
Small Zhang. Play the game ();
Console.writeline ("Now the employee remains:" Xiao Zhang. Salary. Tostring ());
Console.writeline ("Scene");
Console.readline ();
}
}
/ / People responsible for deducting money --- supervisor
Public Class supervisor
{
PUBLIC supervisor ()
{
Console.writeline ("Generated Supervisor");
}
Public Void buckle salary (employee Employee)
{
Console.writeline ("Supervisor: Good boy, work time to play games");
Console.Writeline ("Supervisor: See how much salary your kid" is ");
Console.writeLine ("Start Deduction ...");
System.Threading.Thread.Sleep (1000);
Employee. Salary = Employee. Salary - 500;
Console.writeLine ("" The buckle is executed. ");
}
}
// If you play games, events will trigger events
Public Class employee
{
/ / Preserve employee's salary
PRIVATE INT M_MONEY;
/ / Save the supervisor of the employee
Private supervisor M_Manager;
Public employee (supervisor Manager)
{
Console.writeline ("Generate Personnel.");
m_manager = manager; // Through the constructor, initialize the supervisor of the employee.
m_money = 1000; // Initialize the employee's salary through the constructor.
}
Public int salar / / This property can operate the employee's salary.
{
get
{
RETURN M_MONEY;
}
set
{
M_Money = Value;
}
}
Public void playing games ()
{
Console.writeline ("Employee starts playing games.");
Console.writeline ("Employee: CS is fun, hahaha! I play ...");
System.Threading.Thread.Sleep (1000);
M_Manager. Deduction (this);
}
}
}
Problems brought about this method: the coupling of employees and supervisors is too high.
1. After the executive class must be created in the customer program, it can be generated in the employee class. If you only need the employee object, you have to create the required employee object instance without the competent objective object, you have to go first. Create an object instance of a supervisor;
2, if the scene script (ie customer requirements) has changed
(1), now let a new role (a new class), such as security, instead of the supervisor, responsible for deducting employee salary while employee playing games, then we have to modify employee, perhaps need to modify the supervisor (2) If the scene script adds a new demand, ask employees after playing games, not only to deduct salary, but also deduct points on performance, then we have to modify employees.
(2) Using the implementation of the entrusted:
Here are an example: editing in the C # console application success:
Using system;
Namespace Csharpconsole
{
// Define commission
Public Delegate Void PlayGameHandler (Object Sender, System.EventArgs E);
/ / People responsible for deducting money --- supervisor
Public Class supervisor
{
PUBLIC supervisor ()
{
Console.writeline ("Generated Supervisor");
}
Public Void buckle salary (Object Sender, Eventargs E)
{
Console.writeline ("Supervisor: Good boy, work time to play games");
Console.Writeline ("Supervisor: See how much salary your kid" is ");
Employee = (employee) Sender;
Console.writeLine ("Start Deduction ...");
System.Threading.Thread.Sleep (1000);
Employee. Salary = Employee. Salary - 500;
Console.writeLine ("" The buckle is executed. ");
}
}
// If you play games, events will trigger events
Public Class employee
{
// First define an event, this event means that the employee is playing games.
Public Event PlayGameHandler PlayGame;
/ / Save the variable of employee salary
PRIVATE INT M_MONEY;
Public employee ()
{
Console.writeline ("Generate Personnel.");
m_money = 1000; // Constructor, initialize the employee's salary.
}
Public int salar / / This property can operate the employee's salary.
{
get
{
RETURN M_MONEY;
}
set
{
M_Money = Value;
}
}
Public void playing games ()
{
Console.writeline ("Employee starts playing games.");
Console.writeline ("Employee: CS is fun, hahaha! I play ...");
System.Threading.Thread.Sleep (1000);
System.eventargs e = new evenetargs ();
OnPlayGame (e);
}
Protected Virtual Void OnPlayGame (Eventargs E)
{
IF (PlayGame! = NULL)
{
PlayGame (this, e);
}
}
}
Public class scene
{
[Stathread]
Public static void main (string [] args)
{
Console.writeline ("Scene begins.");
// Generate the subject of the supervisor class
Director Xiao Wang = New Director ();
// Generator class object instance small employee Xiao Zhang = New employee ();
// Set the delegate, designate monitoring
Xiao Zhang.playgame = New PlayGameHandler (Xiao Wang. Deduction);
Console.writeline ("The employee has a salary:" small sheet. Salary. Tostring ());
// Employee start playing games
Small Zhang. Play the game ();
Console.writeline ("Now the employee remains:" Xiao Zhang. Salary. Tostring ());
Console.writeline ("Scene");
Console.readline ();
}
}
}
For the previous question:
1. Decouple the inevitable link between the supervisor and the employee class, can create an instance of the employee object, without the existence of the actual management example;
2. When the customer program is changed:
(1) We only need to modify the customer program, that is, the Class scene in the above example will be delegated to the following:
Security Xiao Li = New Security ();
Xiao Zhang.playgame = New PlayGameHandler (Xiao Li.Berage);
That is, it can be realized by security to deduct the salaries, not to mobilize.
(2), we only need to modify the client, that is, the Class scene in the above example, add a delegation:
Xiao Zhang.playGame = New PlayGameHandler (a certain deduction);
This "a certain" can be a supervisor, or other new roles (new classes), only need to define the active action in the class corresponding to a certain ", without mobilizing work.
Fourth, summary:
Of course, we can still design the decoupling classes without the use of delegates and events, but there will be a lot of classes, interfaces, and associations, etc., increasing the logical complexity of the code and procedures, while in .NET, entrusting and Incident, we only need to have few more code.
The use of the entrusted and events has the following elements:
1
Inspire events
-----
Be
Tony
2
, Object to object events
-----
Be
Director Xiao Wang
3
, Definition commission, you let
Director Xiao Wang
Monitor
Tony
.
If these three elements are satisfied, you have written a complete event.