Implementation of delegates and events in C # Observer

Source: Internet
Author: User
Introduction to server One, delegates

1, the Declaration of the Commission:

<access modifier> Delegate <returnType> HandlerName ([parameters])

For example:

public delegate void Printhandler (String str);



A delegate declaration defines a type that encapsulates a method with a specific set of parameters and a return type. For static methods, the delegate object encapsulates the method to invoke. For instance methods, the delegate object encapsulates both an instance and a method on that instance. If you have a delegate object and a set of appropriate parameters, you can invoke the delegate with these parameters.



2, the use of the Commission:

Using System;



public class MyClass

{

public static void Main ()

{

Printstr myprinter = new Printstr ();

Printhandler MyHandler = null;

MyHandler + = new Printhandler (myprinter.callprint); To instantiate a delegate by linking it to a method

if (myhandler!=null)

MyHandler ("Hello world!"); Invokes a delegate, which is equivalent to the method that the anonymous invocation delegate links

Console.read ();

}

}



public delegate void Printhandler (String str); Declaring a delegate type



public class Printstr

{

public void Callprint (string input)

{

Console.WriteLine (input);

}

}






To use the delegate method in C #:

· The method used to create the delegate must be consistent with the delegate declaration (parameter list, return values are consistent)

· Use + + = to link delegates, unlink, or directly using the Delegate.combine and Delegate.remove methods to implement

· You can use the MulticastDelegate instance method Getinvocationlist () to get all the delegates in the delegate chain

· Cannot compose a delegate that contains out parameters



Ii. Brief introduction to the incident

"Events" in C # is a way for a class to provide notification to customers of that class when something happens.

1, the Declaration of the event:

The declared format is: <access modifier> event <delegate type> EventName



Because you use a delegate to declare an event, you must first declare the delegate type of the event <delegate type> (if not already declared) when declaring an event in the class. We have mentioned the declaration of a delegate type above, but there are stricter rules for declaring the type of delegate used for an event under the. NET Framework:

(1), the Commission type of the event should use two parameters;

(2), two parameters are: to indicate the event source "object source" parameters and encapsulate the event of any other relevant information of the "E" parameter;

The type of (3), "E" parameter should be the EventArgs class or derived from the EventArgs class.

As the following definition:

public delegate void Printhandler (Object Sender,system.eventargs e);



Then we can declare the event of the delegate type

For example:

public event Printhandler Print;

When an event occurs, the delegate that its customer provides to it is invoked.



2. Invoke Event:

After a class declares an event, you can handle the event as if it were a field that handles the indicated delegate type. If no client binds the event, the field is empty, otherwise the field references the delegate that should be invoked when the event is invoked. Therefore, when an event is invoked, it is usually checked for empty before the event is invoked. (Invoke event, that is, triggers an event, only from within the class that declares the event)



if (Print!= null)

{

Print (this,e);

}



3. Event Binding:

From the outside of a class, an event is like a public member of a class, accessed through the form of a class name. event name, but it can only be bound and unbound without other actions.



Class name. Print + + new Printhandler (bound method name)//Bind a method to the Print event

Class name. Print-= new Printhandler (bound method name)//Unbind a method that is bound to a print event from the Print event



Iii. use of Delegates and events

Delegates and events are used more in user interface programs, such as button on the user UI of WinForm or WebForm, and its Click event:

Bind the Button1_Click () method to the Click event on the Button1 of the button control

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 patterns are used in many other places, such as observer mode (OBSERVER) or publish/subscribe (Publish/subscribe): In a class to publish (Publish) an event that can be triggered, Other classes can subscribe to the event (Subscribe). Once the Publisher class triggers the event, the runtime environment immediately informs all subscriber classes that subscribe to the event: this event happened! Thus individual subscriber classes can make their own response (invoke the appropriate method).



Let's take a real example of life to illustrate how to use delegates and events, and the benefits of using delegates and events:



For example, there is a company (scene), you are the boss, you have supervisors and employees, as the boss you will assign (entrust) supervisor to manage the work of employees, if an employee play games, then let a supervisor from the employee's salary deducted 500 yuan of money.

This is the reality of the delegate.

In the writing program, the assumption is that the programmer is the boss, there are two classes for supervisors and employees, and the director of Xiao Wang and staff Xiao Zhang is a two class object instance. The employee class has a method: Play the game, and there is a game-playing event, he will stimulate the event as soon as he plays the game. The charge class is responsible for handling the event, he is responsible for playing the game of the employee's salary deduction 500.



(a) First of all, let's take a look at a design approach that is more common in the case of a delegate (which, of course, 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 ("The scene begins.");

To generate an object instance of a supervisor class Xiao Wang

Supervisor Xiao Wang = new director ();

Generates an object instance of an employee class, specifying his supervisor

Employee Xiao Zhang = new Employee (Xiao Wang);



Console.WriteLine ("The Employee's salary:" + Xiao Zhang. Salary. ToString ());



Employees start playing games

Xiao Zhang. Play the game ();



Console.WriteLine ("Now the employee has left:" + Xiao Zhang. Salary. ToString ());



Console.WriteLine ("Scene End");

Console.ReadLine ();

}

}







The person responsible for withholding money----supervisor

public class Supervisor

{

Public Supervisor ()

{

Console.WriteLine ("Generation Manager");

}



public void deduction Salary (employee employee)

{

Console.WriteLine ("Director: Good boy, work time dare to play games");

Console.WriteLine ("Supervisor: See how much money you Got)";



Console.WriteLine ("Start to deduct salary ...");

System.Threading.Thread.Sleep (1000);



Employee. Salary = employee. Salary-500;



Console.WriteLine ("Deduction of salary execution completed.");

}

}



If you play a game, an event is raised

public class employee

{

Save Employee's salary

private int M_money;

Save the employee's supervisor

Private director M_manager;



Public employee (Supervisor manager)

{

Console.WriteLine ("Generate employee.");

M_manager = Manager; Initializes the employee's supervisor through the constructor.

M_money = 1000; The employee's salary is initialized through the constructor.

}



public int Salary//This property can operate the employee's salary.

{

Get

{

return M_money;

}

Set

{

M_money = value;

}

}



public void Play Game ()

{

Console.WriteLine ("The staff began to play the game ...");

Console.WriteLine ("Staff: CS really fun, haha ha!") I play ... ");

System.Threading.Thread.Sleep (1000);



M_manager. Deduction of salary (this);

}

}

}



The problem with this approach: the coupling between employee class and executive class is too high

1, in the client must first create a supervisor class to generate the employee class, if you do not need a Supervisor class object and only the employee class object, in order to create the desired Employee Class object instance, you also have to create an object instance of the Executive class first;

2, if the scene script (that is, client program requirements) has changed

(1), now to make a new role (a new Class), such as security, to replace the supervisor, in charge of employees when playing games to deduct staff salaries, then we have to modify the employee class, perhaps also need to modify the Executive class;

(2), if the scene script to add new requirements, staff to play the game, not only to deduct salary, but also in the performance of points, then we have to modify the employee class.


(ii) using the implementation of the Commission:



Here's an example: in C # console application editing runs successfully:



Using System;

Namespace Csharpconsole

{

Defining delegates

public delegate void Playgamehandler (Object Sender,system.eventargs e);



The person responsible for withholding money----supervisor

public class Supervisor

{

Public Supervisor ()

{

Console.WriteLine ("Generation Manager");

}



public void Deduction Salary (object Sender,eventargs e)

{

Console.WriteLine ("Director: Good boy, work time dare to play games");

Console.WriteLine ("Supervisor: See how much money you Got)";



Staff employee = (employee) sender;



Console.WriteLine ("Start to deduct salary ...");

System.Threading.Thread.Sleep (1000);

Employee. Salary = employee. Salary-500;

Console.WriteLine ("Deduction of salary execution completed.");

}

}



If you play a game, an event is raised

public class employee

{

First define an event that indicates that the employee is playing the game.

public event Playgamehandler PlayGame;

Variable to save employee salary

private int M_money;



Public employee ()

{

Console.WriteLine ("Generate employee.");

M_money = 1000; Constructor to initialize the employee's salary.

}



public int Salary//This property can operate the employee's salary.

{

Get

{

return M_money;

}

Set

{

M_money = value;

}

}



public void Play Game ()

{

Console.WriteLine ("The staff began to play the game ...");

Console.WriteLine ("Staff: CS really fun, haha ha!") I play ... ");

System.Threading.Thread.Sleep (1000);

System.EventArgs e = new EventArgs ();



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 ("The scene begins.");

To generate an object instance of a supervisor class Xiao Wang

Supervisor Xiao Wang = new director ();

Generate an object instance of an employee class small sheet

Employee Xiao Zhang = new Employee ();



Set the delegate to specify the monitoring

Xiao Zhang. PlayGame + = new Playgamehandler (Xiao Wang, deduction of salary);



Console.WriteLine ("The Employee's salary:" + Xiao Zhang. Salary. ToString ());



Employees start playing games

Xiao Zhang. Play the game ();



Console.WriteLine ("Now the employee has left:" + Xiao Zhang. Salary. ToString ());



Console.WriteLine ("Scene End");

Console.ReadLine ();

}

}

}




For the questions raised earlier:

1, decoupling the executive class and the inevitable link between the employee class, you can create a separate employee class object instances, without having to control whether there is a Supervisor class object instance existence;

2, in the customer program needs change:

(1), we only need to modify the client program, that is, the class scenario in the example above, change the delegate to read as follows:



Security Xiao Li = new security ();

Xiao Zhang. PlayGame + = new Playgamehandler (Xiao Li. Deduction of salary);



can be realized by the security to be responsible for deduction of salary changes in demand, rather than the mobilization of the work class.

(2), we simply modify the client program, that is, the class scene in the example above, add a delegate as follows:



Xiao Zhang. PlayGame + = new Playgamehandler (XXX. Deduction performance score);



This "So-and-so" can be a supervisor, or other new role (new Class), only to be in the "So-and-so" corresponding to the class definition of the action can be deducted performance points, without the mobilization of the work class.



Four, Summary:

Of course, instead of using delegates and events, we can still design decoupled classes, but add a lot of classes, interfaces, and associations, and so on, increasing the amount of code and the logic complexity of the program, and in. NET we need a lot less code to implement the delegate and the event.



There are several elements to use for delegates and events:


1, the object of the event-----is the employee Xiao Zhang
2, the object of processing object events-----is the director Xiao Wang
3, the definition of entrustment, is that you let the director Xiao Wang monitoring staff Xiao Zhang.

If all three elements are satisfied, then you write a complete event processing.


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.