События C# в программировании чем-то похожи на события в повседневной жизни. Рождение, первый шаг, первый день в школе и тому подобное. Разумеется, для программы значимые события выглядят немного иначе. К примеру, загрузилась форма, изменилось значение поля или был создан объект. Понимать события крайне полезно. Но в первую очередь необходимо изучить делегаты C#.
Делегаты C#
Итак, механика событий достаточно проста. Предположим, для класса Character, рассмотренного ранее, мы хотим создать событие. У персонажа могут меняться любые параметры. Для начала обработаем изменение имени персонажа. Персонаж в данном случае является издателем события. Другие классы могут подписаться на получение этого event. Чтобы издатель смог вызвать метод подписчика, зарегистрированный на события, методы должны иметь определенный формат.
И вот мы вплотную подошли к делегатам. По сути своей, это тип, определяющий полную сигнатуру метода события. К примеру, так описывается делегат, не имеющий параметров.
/// <summary> /// Делегат. /// </summary> /// <param name="sender"> Объект - отправитель события.</param> /// <param name="e"> Передаваемые аргументы.</param> public delegate void EventHandler (Object sender, EventArgs e)
На самом деле, подобное описание делегатов не обязательно. Однако рекомендуется использовать общепринятое соглашение: первый параметр — издатель, второй — объект с параметрами. Класс EventArgs не содержит данных по событию. При необходимости передать что-либо подписчику, необходимо унаследовать этот класс и наделить потомка необходимыми свойствами.
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
События C# и их вызовы
Делегат, в первую очередь, описывает метод подписчика. Также делегат сообщает издателю, какой метод будет вызван. Делегаты одного класса могут использоваться в разных событиях и издателях. Итак, добавим событие с именем NameChanged класса EventHandler.
public event EventHandler NameChanged;
Обязательно нужно указывать модификатор public, чтобы к событию был доступ извне. Для генерации event нужно просто вызвать его, как обычный метод.
NameChanged(this, new EventArgs());
Далее, рассмотрим, как может выглядеть свойство Name.
/// <summary> /// Закрытое поле "Имя". /// </summary> private string _name; /// <summary> /// Свойство "Имя". /// </summary> public string Name { get { return _name; } set { if (value == "" || value == string.Empty) { throw new ArgumentException("Укажите имя."); } _name = value; if (NameChanged != null) { NameChanged(this, new EventArgs()); } } }
И, соответственно, рассмотрим пример использования в консольном приложении.
static void Main(string[] args) { var character = new Character(); character.NameChanged += new EventHandler(NameChanged); character.Name = "Гудини"; Console.ReadLine(); } /// <summary> /// Событие изменения имени. /// </summary> /// <param name="sender"> Издатель.</param> /// <param name="e"></param> public static void NameChanged(Object sender, EventArgs e) { Character character = (Character)sender; Console.WriteLine($"Новое имя персонажа {character.Name}."); }
Для того, чтобы добавить обработчик события, используется +=. Если же нужно обработчик удалить, используется -=. Первое время делегаты выглядят сложно и запутанно, однако спустя пару опытов, жизнь становится значительно проще.
Анонимные методы
Рассмотренный ранее вариант обработки событий прекрасен. Однако когда для реализации делегата достаточно пары строк, писать подобный код нерационально. Да и скучно, если таких событий множество. Для подобных ситуаций есть анонимные метод, позволяющие обрабатывать event. Рассмотрим обработку изменения имени при помощи анонимного метода.
static void Main(string[] args) { var character = new Character(); character.NameChanged += delegate (Object sender, EventArgs e) { Character person = (Character)sender; Console.WriteLine($"Новое имя персонажа {person.Name}."); }; character.Name = "Гудини"; Console.ReadLine(); }
После ключевого слова delegate в скобках указаны параметры, передаваемые обработчику события. Реализация обработки события описывается в круглых скобках. Анонимным метод зовется потому, как не имеет явно указанного имени.
Полагаю, это достаточный минимум для начала работы с событиями и делегатами. Удачных вам экспериментов, коллеги.
Кроме того, рекомендую прочитать статью Переменные C#. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.