C # Delegate, event (3) -- event

Source: Internet
Author: User

Directory

  1. Event Overview
  2. Observer Mode

In the previous section, we conducted research on the one hand by delegation. In this section, we will explore events on the other hand, hoping to leave valuable information to everyone.

  • Event Overview

Anyone who has developed MFC knows that the Windows message mechanism studied when learning MFC is like this-first, the application enters the message listening loop (Message listener) from the WinMan function, if a user triggers an event, the message listener routes the message to the process function (message processing function) to process the Event-related logic.

This is like in the form application, the main form has a button Bt01. When you click this button, the system pushes the user-clicked button to the Message Queue for medium waiting for processing, the system routes the time slice to the application to call the registered process function processing logic. Here, the process function is the event processing method we usually write.

In object-oriented programming, the event mode is somewhat different .. . NET Library encapsulates Windows messages into events, so that the two objects can communicate with each other through events, and the delegate is used to encapsulate event processing methods, is the registration of event processing functions.

  • Observer Mode

I personally think that this mode can clearly describe the event's working mode. The following describes in detail the case of boiling water.

At present, the main steps in the process of boiling water are as follows: 1. boil water, 2. when the water is boiling, the whistle prompts, 3. after 30 seconds, the system automatically cut off the power to stop boiling water.

Therefore, we can design the Code as follows:

Public class Heater {private int timer; // after the water is burned out, the whistle timer private Boolean boiling; // water boiling switch /// <summary> // water boiling in the kettle /// </summary> public void BoilWater () {int temp = 0; boiling = true; while (boiling) {if (temp <= 100) {temp ++;} else {AlertTip () ;}if (timer = 30) {ShutDown ();}}} /// <summary> /// whistle alarm and timing /// </summary> private void AlertTip () {timer ++; Console. writeLine ("Alarm: water is almost boiling! ") ;}/// <Summary> /// automatically shut down, stop boiling water /// </summary> private void ShutDown () {boiling = false; Console. writeLine ("ShutDown: automatic trip, stop boiling water! ") ;}} Class Program {static void Main () {Heater ht = new Heater (); ht. BoilWater ();}}

In the above Code, we define a kettle type Heater. There are three methods in Heater: BoilWater () -- boiling water; AlertTip () -- boiling water with a whistle prompt; ShutDown () -- The Whistle automatically trips to stop boiling water after half a minute. This design requires the water bottle manufacturer to produce boiling water equipment and alarm equipment. However, if the kettle is made up of a trip-able kettle and an alarm produced by the kettle manufacturer and the alarm manufacturer, how can we set it? The above code is obviously unable to meet the requirements, and now you need to use the event.

First, simulate the components in the preceding steps into their respective types, and modify the code:

Public class Heater {public Boolean boiling; // set the public event AlertEventHandle AlertEvent; // <summary> /// set the kettle to boiling water /// </summary> public void BoilWater () {int temp = 0; boiling = true; while (boiling) {if (temp <100) {temp ++;} else {if (AlertEvent! = Null) AlertEvent () ;}} public void ShutDown () {boiling = false; Console. WriteLine ("ShutDown: automatic trip, stop boiling water! ") ;}} Public class Alert {public event ShutEventHandle ShutEvent; private int timer; // after the water is burned out, the whistle timer public Alert () {timer = 0 ;} /// <summary> /// whistle alarm and timing /// </summary> public void AlertTip () {if (timer <30) {timer ++; Console. writeLine ("Alarm: water is almost boiling! ");} Else {if (ShutEvent! = Null) ShutEvent ();}}}

In addition, in this namespace, declare the following delegate-event processing carrier. The Code is as follows:

    public delegate void AlertEventHandle(Heater par);    public delegate void ShutEventHandle(Heater par);

Of course, the main function also needs to be slightly changed:

 class Program    {        static void Main()        {            Heater heater = new Heater();            Alert alert = new Alert();            AotuShut aotuShut = new AotuShut();            heater.AlertEvent += alert.AlertTip;            heater.ShutEvent += aotuShut.ShutDown;            heater.BoilWater();        }    }

The running result is as follows:

In the modified Code, the Heater class declares the whistle event AlertEvent; the Alert class also declares the automatic trip event ShutEvent.

Let's take a look at how the boiling water works after the event is used. In the Main function, first create a kettle object and an Alert (Alarm) object, and then separate the Alert class member Methods AlertTip () -- whistle -- register to the water bottle Class Object and ShutDown the water bottle class member method () -- automatic trip -- register to the alarm object. Then, execute the water burning action. When the water is boiling, the Heater class sends a notification to the Alert Class Object alert to execute the whistle and time; 30 seconds later, the alarm whistle will notify the kettle object heater to stop boiling water automatically.

All code:

Using System; using System. collections. generic; using System. linq; using System. text; namespace ConsoleApplication1 {public delegate void AlertEventHandle (); public delegate void ShutEventHandle (); public class Heater {public Boolean boiling; // open public event using AlertEvent; /// <summary> /// boiling water in the kettle /// </summary> public void BoilWater () {int temp = 0; boiling = true; while (boiling ){ If (temp <100) {temp ++;} else {if (AlertEvent! = Null) AlertEvent () ;}} public void ShutDown () {boiling = false; Console. WriteLine ("ShutDown: automatic trip, stop boiling water! ") ;}} Public class Alert {public event ShutEventHandle ShutEvent; private int timer; // after the water is burned out, the whistle timer public Alert () {timer = 0 ;} /// <summary> /// whistle alarm and timing /// </summary> public void AlertTip () {if (timer <30) {timer ++; Console. writeLine ("Alarm: water is almost boiling! ");} Else {if (ShutEvent! = Null) ShutEvent () ;}} class Program {static void Main () {Heater heater = new Heater (); Alert alert = new Alert (); heater. alertEvent + = alert. alertTip; alert. shutEvent + = heater. shutDown; heater. boilWater ();}}}

There are two groups of actions. One is to notify the kettle to trigger the whistle, and the other is to notify the kettle to stop boiling water. Both actions have two roles: observer and sender. When the water bottle notifies the alarm, the water bottle is the sender, the alarm is the observer, and the water bottle is the Observer at the same time when the trip, the alarm is the sender. In C #, the observer does not know any information about the sender. Therefore, the observer must be associated with the sender using the delegate. Therefore, the event is of the delegate type.

Next, let's take a look at the event registration in the Main function using "+ =". Why don't we use "=? After it is changed to "=", the compilation error will be recycled: The following must be used by Heater. AlertEvent: + = or-=...

Why? In fact, when declaring an event, although we declare the Public type, the system still converts the event to the private type during compilation, as shown in the public event ShutEventHandle ShutEvent; convert to private event ShutEventHandle ShutEvent;

The following code is also generated:

    [MethodImpl(MethodImplOptions.Synchronized)]    public void add_AlertEvent(AlertEventHandle value)    {        this.AlertEvent = (AlertEventHandle) Delegate.Combine(this.AlertEvent, value);    }    [MethodImpl(MethodImplOptions.Synchronized)]    public void remove_AlertEvent(AlertEventHandle value)    {        this.AlertEvent = (AlertEventHandle) Delegate.Remove(this.AlertEvent, value);    }

In this way, the event cannot be assigned with "=". Using "+ =" and "-=" is equivalent to calling the add_AlertEvent () and remove_AlertEvent () methods described above, the two methods are to add the event processing function to or delete it from the delegate chain.

Summary:

Although the arguments are not based on the concepts of events and other dogmas, they also describe the working principles of events in an example. NET has many conventions. For example, when declaring the event processing function, the method name is added "On" before the event name ". With these conventions, we can write better code.

C # events and delegation are a threshold for beginners. It is very easy to discover only when they have crossed this threshold and then look back at the delegation and events.

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.