Detailed description of delegation and events in C # (4)

Source: Internet
Author: User
Tags prototype definition
There are many examples like this. gof abstracts it and is called the observer design pattern:The observer design mode is used to define a one-to-many dependency between objects, so that when the state of an object changes, other objects dependent on it will be automatically notified and updated. The observer mode is a loosely coupled design mode.
We have already introduced a lot of delegation and events in the Observer Design Mode for implementation examples. Now it is easy to write code. Now we will give the code directly here and describe it in the annotations.
Using system;
Using system. Collections. Generic;
Using system. text;

Namespace delegate {
// Water Heater
Public class heater {
Private int temperature;
Public Delegate void boilhandler (int param); // declare the delegate
Public event boilhandler boilevent; // declare an event

// Boil water
Public void boilwater (){
For (INT I = 0; I <= 100; I ++ ){
Temperature = I;

If (temperature> 95 ){
If (boilevent! = NULL) {// if an object is registered
Boilevent (temperature); // call the methods of all registered objects
}
}
}
}
}

// Alarm
Public class alarm {
Public void makealert (int param ){
Console. writeline ("alarm: Tick, water has been {0} degrees:", Param );
}
}

// Display
Public class display {
Public static void showmsg (int param) {// static method
Console. writeline ("display: The water is almost burned out. Current temperature: {0. ", Param );
}
}

Class program {
Static void main (){
Heater heater = new heater ();
Alarm alarm = new alarm ();

Heater. boilevent + = alarm. makealert; // Registration Method
Heater. boilevent + = (new alarm (). makealert; // Method for registering anonymous objects
Heater. boilevent + = display. showmsg; // register the static method

Heater. boilwater (); // The method of boiling water, which automatically calls the method of registering an object
}
}
}
Output:
Alarm: The water is 96 degrees away:
Alarm: The water is 96 degrees away:
Display: the water is boiling. The current temperature is 96 degrees.
// Omit...
The delegate and event in. NET Framework, although the above example has done the work we want to do well, we are not only confused: Why is the event model in. NET Framework different from the above? Why are there many eventargs parameters?
Before answering the above questions, we should first understand the encoding specifications of. NET Framework:

  • The name of the delegate type should end with eventhandler.
  • Prototype definition of the delegate: There is a void returned value, and two input parameters are accepted: an object type, and an eventargs type (or inherited from eventargs ).
  • The event is named as the part left after the eventhandler is removed by the delegate.
  • The types inherited from eventargs should end with eventargs.

Next, let's explain:

  • The parameter of the object type in the delegate declaration prototype represents the subject, that is, the monitoring object. In this example, it is the heater (water heater ). A callback function (such as makealert of alarm) can be used to access the event-triggered object (heater ).
  • The eventargs object contains the data that the observer is interested in. In this example, It is temperature.

In fact, the above is not only for coding specifications, but also makes the program more flexible.For example, if we not only want to get the temperature of the water heater, but also want to get its production date, model, and price in the observer side (alarm or display) method, the delegation and method declaration will become very troublesome. If we pass the water heater reference to the method of the alarm, we can directly access the water heater in the method.
Now we can rewrite the previous example to make it conform to. NET Framework specifications:
Using system;
Using system. Collections. Generic;
Using system. text;

Namespace delegate {
// Water Heater
Public class heater {
Private int temperature;
Public string type = "realfire 001"; // Add a model for demonstration
Public String area = "China Xian"; // Add the origin as a demo
// Declare the delegate
Public Delegate void boiledeventhandler (Object sender, boiledeventargs E );
Public event boiledeventhandler boiled; // declare the event

// Define the boiledeventargs class and pass the information to the observer.
Public class boiledeventargs: eventargs {
Public readonly int temperature;
Public boiledeventargs (INT temperature ){
This. temperature = temperature;
}
}

// The class inherited from heater can be rewritten so that the inherited class rejects the monitoring of other objects.
Protected virtual void onboiled (boiledeventargs e ){
If (boiled! = NULL) {// if an object is registered
Boiled (this, e); // call the method of all registered objects
}
}

// Boil water.
Public void boilwater (){
For (INT I = 0; I <= 100; I ++ ){
Temperature = I;
If (temperature> 95 ){
// Create a boiledeventargs object.
Boiledeventargs E = new boiledeventargs (temperature );
Onboiled (E); // call the onbolied Method
}
}
}
}

// Alarm
Public class alarm {
Public void makealert (Object sender, heater. boiledeventargs e ){
Heater heater = (heater) sender; // are you familiar with this?
// Access public fields in sender
Console. writeline ("alarm: {0}-{1}:", heater. Area, heater. type );
Console. writeline ("alarm: Tick, water has {0} degrees:", E. Temperature );
Console. writeline ();
}
}

// Display
Public class display {
Public static void showmsg (Object sender, heater. boiledeventargs e) {// static method
Heater heater = (heater) sender;
Console. writeline ("display: {0}-{1}:", heater. Area, heater. type );
Console. writeline ("display: The water is almost burned out. Current temperature: {0. ", E. Temperature );
Console. writeline ();
}
}

Class program {
Static void main (){
Heater heater = new heater ();
Alarm alarm = new alarm ();

Heater. Boiled + = alarm. makealert; // Registration Method
Heater. Boiled + = (new alarm (). makealert; // Method for registering anonymous objects
Heater. Boiled + = new heater. boiledeventhandler (alarm. makealert); // You can also register
Heater. Boiled + = display. showmsg; // register the static method

Heater. boilwater (); // The method of boiling water, which automatically calls the method of registering an object
}
}
}

Output:
Alarm: China Xian-realfire 001:
Alarm: The water is 96 degrees away:
Alarm: China Xian-realfire 001:
Alarm: The water is 96 degrees away:
Alarm: China Xian-realfire 001:
Alarm: The water is 96 degrees away:
Display: China Xian-realfire 001:
Display: the water is boiling. The current temperature is 96 degrees.
// Omit...
Summary
In this article, I first introduced the concept of delegation, what to do with delegation through a greetingpeople applet, and then introduced the event, next, we will give a rough description of the intermediate code generated by the delegate and event.
In the second example of a slightly complex water heater, I briefly introduced the observer design mode, completed the mode by implementing this example, and then described it.. NET Framework.

 

Example:

Using system;
Using system. Collections. Generic;
Using system. text;

Namespace delegate
{
/*
* When a mouse came out to find food and was scrambling for food, one of them suddenly found a cat, so he shouted: the cat is coming, and everyone is running fast.
* The mouse call caught the attention of the cat. The cat was so happy to see so many foods, so it was also called.
* The cat woke up the sleeping host, so the host spoke and looked at it.
*/
Class mouse
{
Public Delegate void mousedelegate (Object sender, mouseeventargs E); // declare the delegate
Public event mousedelegate calleventhandler; // declare the event

Private bool seecat = false; // whether a cat is found

Public class mouseeventargs: eventargs
{
Public int mousenumber = 10;
Public mouseeventargs (INT number)
{
This. mousenumber = number;
}
}

Public void called (Object sender, mouseeventargs E)
{
Console. writeline );
Console. writeline ("---------- the above is the mouse action -----------");
}
Public void findfood ()
{
For (INT I = 10; I <24; I ++)
{
If (I = 18)
{
Console. writeline ("at, the mouse came out and walked ....");
}
If (I = 20)
{
Console. writeline ("at, the mouse is looking for food ....");
}
If (I = 21)
{
Console. writeline ("at, the mouse finds the food and starts enjoying the delicious meal ....");
}
If (I = 22)
{
Console. writeline ....");
}
If (I = 23)
{
Console. writeline ("A mouse suddenly finds a cat while the mouse is not ready for communication ....");
Seecat = true;
Break;
}
}
If (seecat)
{
Mouseeventargs E = new mouseeventargs (10 );
Seecat (E );
}
}

Public Virtual void seecat (mouseeventargs E)
{
If (calleventhandler! = NULL)
{
Calleventhandler (this, e );
}
}
}

Class cat
{
Public void hear (Object sender, mouse. mouseeventargs E)
{
Console. writeline ("The Cat thought: I heard the mouse call. Hey, the meal is coming! ");
Walking (E );
}

Private void walking (mouse. mouseeventargs E)
{
Console. writeline ("The Cat goes fast to the mouse's voice ...");
See (E );
}

Private void see (mouse. mouseeventargs E)
{
Console. writeline ("The Cat sees the mouse .");
Called (E );
}

Private void called (mouse. mouseeventargs E)
{
Console. writeline ("The Cat said ecstatic: Wow! So many mice, I count... Oh, my God! A total of {0} mice... ", E. mousenumber );
Console. writeline ("---------- the above is the cat action -----------");
}
}

Class human
{
Public void hear (Object sender, mouse. mouseeventargs E)
{
Called ();
}

Private void called ()
{
Console. writeline ("the host said: this dead cat does not let people go to bed! Let's see what happened? ");
Walking ();
}

Private void walking ()
{
Console. writeline ("Go go! ");
Console. writeline ("---------- and above are human actions -----------");
}
}

Class Program
{
Static void main ()
{
Mouse M = new mouse ();
M. calleventhandler + = M. called;
Cat c = new CAT ();
M. calleventhandler + = C. Hear;
Human man = new human ();
M. calleventhandler + = man. Hear;
M. findfood ();
String A = console. Read (). tostring ();
}
}
}

 

Related Article

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.