События

 

Способ описания одного объекта с другим по действиям.

Три этапа:

объявление события (publishing);

регистрация получателя события (subscribing);

       – генерация события (raising).

 

<модификаторы> event <тип делегата> <имя события>;

 

Ключевое слово event указывает на объявление события. При объявлении события требуется указать делегат, описывающий метод обработки события. Обычно этот делегат имеет тип возвращаемого значения void.

Фактически, события являются полями типа делегатов. При объявлении события компилятор добавляет в класс или структуру private-поле с именем <имя события> и типом <тип делегата>. Кроме этого, для обслуживания события компилятор создаёт два метода add_Name() и remove_Name(), где Name – имя события. Эти методы содержат код, добавляющий и удаляющий обработчик события в цепочку группового делегата, связанного с событием.

Если программиста по каким-либо причинам не устраивает автоматическая генерация методов add_Name() и remove_Name(), он может описать собственную реализацию данных методов. Для этого при объявлении события указывается блок, содержащий секции add и remove:

<модификаторы> event <тип делегата> <имя события>

{

    add { <блок кода> }

    remove { <блок кода> }

    };

Для генерации события в требуемом месте кода помещается вызов в формате <имя события>(<фактические аргументы>).

 

using System;

public delegate void Handler(int val);

 

    public class ExampleClass

    {

        private int _field;

 

        public int Field

        {

            get { return _field; }

            set

            {

                _field = value;

                if (value < 0)

                {

        // проверка нужна, чтобы предотвратить генерацию

                    // исключительной ситуации

                    if (NegativeValueSet != null)

                    {

                        NegativeValueSet(value);

                    }

                }

            }

        }

        public event Handler NegativeValueSet;

    }

   

class MainClass

{

   public static void Reaction(int i)

   {

      Console.WriteLine("Negative value = {0}", i);

   }

   static void Main(string[] args)

   {

     var c = new ExampleClass();

     c.Field = -10;   // нет обработчиков, нет реакции на событие

 

     // назначаем обработчик

     c.NegativeValueSet += Reaction;

     c.Field = -20;// вывод: "Negative value = -20"

 

     // назначаем еще один обработчик в виде лямбда-оператора

     c.NegativeValueSet += i => Console.WriteLine(i);

     c.Field = -30; // вывод: "Negative value = -30" и "-30"

 

      // удаляем первый обработчик

      c.NegativeValueSet -= Reaction;

      Console.ReadLine();

     }

    }

 

Платформа .NET предлагает средства стандартизации работы с событиями. В частности, для типов событий зарезервированы следующие делегаты:

public delegate void EventHandler(object sender, EventArgs e);

 

public delegate void EventHandler<T>(object sender, T e)  where T : EventArgs;

public class ExampleClass: EventArgs