Блог
  • Начало
  • Обо мне
  • Обратная связь

C#: События (events)

Дата и время: 2 июня 2015 г. 22:10 | Категория: Программирование, C#

В отличии от многих других языков программирования, C# "из коробки" предоставляет возможность реализации событийного управления. Данный подход позволяет значительно упростить логику программы и реализован очень просто и элегантно.

Рассмотрим небольшой пример создания события на примере абстракции почтового ящика. Опишем простой класс с единственным методом - добавлением письма. Допустим, что нам требуется выполнять какое-либо действие при каждом добавлении письма (возможно какие-либо вычисление, а возможно - оповещение других объектов). Следующий код демонстрирует как это реализовать. При добавлении письма, выводится сообщение: "Получено письмо!"

using System;

namespace App
{
    // Описываем делегат (читай - прототип) будущего события
    public delegate void LetterReceived(object sender, EventArgs e);

    public class Mailbox
    {
        // Создаём объект события внутри класса, чтобы к нему можно было подписаться
        public event LetterReceived OnLetterReceived;

        public void AddLetter(string letter)
        {
            // Проверяем, есть ли подписчики на событие
            if (OnLetterReceived != null)
            {
                // Вызываем событие. Первый аргумент - инициатор события,
                // второй - дополнительные аргументы события.
                OnLetterReceived(this, new EventArgs());
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var mailbox = new Mailbox();
            // Подписывается на событие
            mailbox.OnLetterReceived += mailbox_OnLetterReceived;
            mailbox.AddLetter("Письмо");

            Console.Read();
        }
        
        // Реализуем обработчик события
        static void mailbox_OnLetterReceived(object sender, EventArgs e)
        {
            Console.WriteLine("Получено письмо!");
        }
    }
}

Как видно, всё очень просто и этого достаточно для начала работы. Но со временем может потребоваться добавить свои аргументы событию. В классическом виде это реализуется путём наследования от класса EventArgs с добавлением необходимых полей. Например, рассмотрим тот же код, но уже передающий текст письма в аргументе события.

using System;

namespace App
{
    // Описываем свой класс аргументов событий, определяя поле для письма
    public class MailEventArgs : EventArgs
    {
        public string Letter { get; set; }
    }
    
    // Заменяем тип второго параметра делегата на наш класс
    public delegate void LetterReceived(object sender, MailEventArgs e);

    public class Mailbox
    {
        public event LetterReceived OnLetterReceived;

        public void AddLetter(string letter)
        {
            if (OnLetterReceived != null)
            {
                // Создаём объект аргумента события и помещаем в него текст письма
                var e = new MailEventArgs { Letter = letter };
                OnLetterReceived(this, e);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var mailbox = new Mailbox();
            mailbox.OnLetterReceived += mailbox_OnLetterReceived;
            mailbox.AddLetter("Письмо");

            Console.Read();
        }

        static void mailbox_OnLetterReceived(object sender, MailEventArgs e)
        {
            // Добавляем к выводу сообщения текст полученного письма
            Console.WriteLine(String.Format("Получено письмо!\nТекст: {0}", e.Letter));
        }
    }
}

Таким образом, события очень удобны. По сути, они могут заменить шаблон проектирования Наблюдатель (Observer), но между данными подходами всё же есть некоторые отличия. Наблюдатель предполагает передачу в качестве подписчика объект, а событие предполагает обработчик в виде метода. Так или иначе, обоими способами можно добиться одинаковых результатов.

comments powered by Disqus
Select language:
  • Русский
  • English

  • Программирование

    Python C++ JavaScript

    Веб-разработка

    Django ASP.NET

    Мобильная разработка

    Windows Phone Android

    Разработка игр

    Unity3d Blender

    Артем Устимов © 2014