Events and delegates. The concept of event. Interaction between events

Events and delegates. The concept of event. Interaction between events


Content


 1. What is an event in C#? What is the usefulness of events in C#?

An event is an automatic message that an action has taken place in the program.

To execute this or that event, the program can respond accordingly. The reaction to the event is carried out using the so-called event handlers. The event handler is a common method that performs some actions in the program, in the event that an event has been generated.

Events work in conjunction with delegates. This combination allows you to create lists (chains) of event handlers (methods) that must be called when this event is called (started, generated). This approach is effective when writing large software systems, because it allows you to order a large complex code in which it is very easy to make a logical mistake.

Figure 1 schematically shows how is realized work of the MyEvent event.

 

Figure 1. Calling the method chain for the MyEvent event

 

2. What is the general form of an event declaration? The event keyword. Example

The event is declared based on the previously declared delegate type. General form of the event declaration:

event event_delegate event_name;

where

  • even_delegate – the name of the delegate type that is used to declare the event;
  • event_name – the specific name of the object (variable) of the event type.

Example. Declaration an event named MyEvent based on the delegate type MyDelType.

event MyDelType MyEvent;

For more information about declaring a delegate type and declaring a delegate variable, see the topic:

 

3. What are the requirements for the delegate that will be used to process the event?

In order to be able to process (launch) the list of event handlers, the delegate should not return a value. That is, a delegate can return a void type.

If the delegate returns a value, the last method (handler) from the generated list of methods is called.

 

4. What are the requirements for a method that can be a handler for some event?

The main requirement is that the method can have exactly the same signature as the delegate, on the basis of which the event is declared.

If you want to organize a list of methods that are called when an event is called, then the delegate type and method must return a value of void type (do not return anything). If there is a list of methods that return a value, then the last method is called when the event is started from this list.

 

5. How is the method registered in the event? En example

To register a method for processing this event, use the ‘=’ or ‘+ =’ operators.

Example.

Let in the body of a certain class be declared:

  • an event named MyEvent;
  • event handling method (event handler) MyMethod1();
  • event handler MyMethod2();
  • event handler MyMethod3().

The methods have exactly the same signature as the delegate type, on the basis of which the MyEvent event was declared.

To register the MyMethod1(), MyMethod2(), MyMethod3() methods for the MyEvent event, you need to write the following code:

...

// the registering of methods for the MyEvent event
MyEvent = MyMethod1();  // MyEvent => MyMethod1
MyEvent += MyMethod2(); // MyEvent => MyMethod1 -> MyMethod2
MyEvent += MyMethod3(); // MyEvent => MyMethod1 -> MyMethod2 -> MyMethod3

...

In this case, a list (chain) of three methods is formed. The methods in the list follow in the same order in which they were registered (added) to the event.

If the methods do not return any value, then when the event is called, all methods from the list will be executed in the order of their addition. If the methods return a value, then the last method from the list will be executed when the event is called.

 

6. What is the sequence of steps in the program to organize the list of events that will be called when the event is called (launched)

To organize the list of event handlers (methods), you need to perform the following sequence of steps:

  1. Declare the type of delegate in the class.
  2. Declare an event in this class or create another class that contains the event declarations.
  3. In some method (in the program code), create a list of handlers (methods) that will be called when this event is called. This is done using the ‘=’ and ‘+ =’ operators. Creating a list means registering handlers for this event.
  4. Call the event (run) from this method.

 

7. An example of using an event for a case if methods and events are declared in the same class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TrainEvents03
{
    public partial class Form1 : Form
    {
        // 1. Declare the delegate type
        delegate void CalcFigure(double R);

        // 2. Declare the event named ECF
        event CalcFigure ECF;

        // 3. The methods of event handler are placed in the same class
        //   The methods have exactly the same signature as the CalcFigure delegate type
        // Circumference based on the radius R
        void GetLength(double R)
        {
            double res;
            const double Pi = 3.1415;
            res = 2 * Pi * R;
            label1.Text = "Circumference = " + res.ToString(); // display on a form
        }

        // Area of a circle
        void GetArea(double R)
        {
            double res;
            const double Pi = 3.1415;
            res = Pi * R * R;
            label2.Text = "Area of a circle = " + res.ToString(); // result on the form
        }

        // Volume of a sphere
        void GetVolume(double R)
        {
            double res;
            const double Pi = 3.1415;

            res = 4.0 / 3.0 * Pi * R * R * R;
            label3.Text = "The volume of a sphere = " + res.ToString();
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 4. Demonstration of working with methods using an event
            // 4.1. Create a chain of methods that will be called from the ECF event
            ECF = GetLength; // ECF => GetLength()
            ECF += GetArea; // ECF => GetLength() -> GetArea()
            ECF += GetVolume; // ECF => GetLength() -> GetArea() -> GetVolume()

            // 4.2. Calling the ECF event with parameter 2.0
            ECF(2.0); // The three methods GetLength(), GetArea(), GetVolume() are called

            // Calling an event for parameter 3.5
            ECF(3.5);
        }
    }
}

 

8. An example of using an event that is declared in a separate class. Event handlers are declared in another class

Let in CalcFigures.cs module is declared a class that contains the following description

namespace TrainEvents05
{
    class CalcFigures
    {
        // class containing event handling methods
        public void GetLength(double r, ref double L)
        {
            L = (double)(2 * 3.1415 * r);
        }

        public void GetArea(double r, ref double S)
        {
            S = (double)(3.1415 * r * r);
        }
    }
}

In another module Form1.cs, a class is declared that demonstrates the use of methods from the CalcFigures class. The listing of the Form1.cs module is as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TrainEvents05
{
    public partial class Form1 : Form
    {
        // declaring the delegate type
        delegate void CalcFig(double r, ref double l);

        // declaring an event based on the CalcFig type
        event CalcFig EvCF;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Demonstration of using the EvCF event
            CalcFigures CF = new CalcFigures(); // CF - instance of the class object
        
            double len, r;
            r = 1.0;
            len = 0;
            EvCF = CF.GetLength;

            // run the event
            EvCF(r, ref len); // len = 6.238 - circumference

            // remove from list
            EvCF -= CF.GetLength;

            // add another method to the list
            EvCF += CF.GetArea;

            // run the event
            EvCF(r, ref len); // len = 3.1415 - area of a circle

            label1.Text = len.ToString();
        }
    }
}

 


Related topics