На этом шаге мы рассмотрим использование событий в структурах.
В структурах можно объявлять и использовать события. Логика действий в этом случае такая же, как и при использовании событий в классах. Небольшой пример, дающий общее представление об использовании событий в структурах, представлен в примере ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr200_1 { // Объявление делегата: delegate void MyDelegate(string t); // Первая структура: struct Alpha { // Открытое текстовое поле: public string name; // Закрытое поле, являющееся ссылкой // на экземпляр делегата: private MyDelegate myevent; // Объявление события: public event MyDelegate MyEvent { // Аксессор для добавления ссылки на метод // в список обработчиков события: add { myevent += value; } // Аксессор для удаления ссылки на метод // из списка обработчиков события: remove { myevent -= value; } } // Конструктор: public Alpha(string t) { // Значения полей: name = t; myevent = null; } // Метод для генерирования событий: public void RaiseMyEvent() { // Если ссылка не пустая, то вызывается // экземпляр делегата: if (myevent != null) myevent("Alpha: " + name); } } // Вторая структура: struct Bravo { // Открытое текстовое поле: public string name; // Объявление события: public event MyDelegate MyEvent; // Метод для генерирования события: public void RaiseMyEvent() { // Если список обработчиков не пустой, то // генерируется событие: if (MyEvent != null) MyEvent("Bravo: " + name); } } // Класс с главным методом: class Program { // Статический метод: static void show(string t) { Console.WriteLine("Произошло событие"); Console.WriteLine(t); Console.WriteLine("------------------"); } // Главный метод: static void Main() { // Создание экземпляра первой структуры: Alpha A = new Alpha("Экземпляр A"); // Добавление ссылки на метод в список обработчиков // события: A.MyEvent += show; // Генерирование события: A.RaiseMyEvent(); // Создание экземпляра второй структуры: Bravo B = new Bravo(); // Присваивание значения текстовому полю: B.name = "Экземпляр B"; // Добавление ссылки на метод в список обработчиков // события: B.MyEvent += show; // Генерирование событие: B.RaiseMyEvent(); // Задержка: Console.ReadLine(); } } }
Ниже показано, как выглядит результат выполнения программы:
Рис.1. Результат выполнения программы
В программе есть объявление делегата MyDelegate, соответствующего методам с текстовым аргументом, которые не возвращают результат. Экземпляры этого делегата мы планируем использовать для обработки событий. Также мы описали две структуры Alpha и Bravo. Структуры функционально схожи, но немного по-разному организованы. В структуре Alpha есть открытое текстовое поле name. Закрытое поле myevent типа MyDelegate является ссылкой на экземпляр делегата. Мы это поле используем при описании аксессоров события MyEvent: при добавлении ссылки на метод в список обработчиков события или удалении ссылки из списка в действительности изменения происходят с полем myevent. В структуре также есть конструктор с текстовым аргументом. Текстовый аргумент определяет значение текстового поля name, а поле myevent в качестве значения получает пустую ссылку. В данном случае это момент не тривиальный, поскольку в конструкторе должны быть присвоены значения всем полям экземпляра структуры.
Для генерирования события в структуре описан метод RaiseMyEvent(), в теле которого проверяется условие myevent!=null (истинно, если поле myevent содержит ссылки на методы), и при истинном условии командой
myevent("Alpha: " + name);
Вторая структура называется Bravo. В ней также есть текстовое поле name. Событие MyEvent объявлено без явного описания аксессоров. Конструктора у структуры нет. Метод RaiseMyEvent() генерирует событие MyEvent при условии, что для события зарегистрированы обработчики.
Для обработки событий мы описали статический метод show() с текстовым аргументом. Метод при вызове отображает значение своего текстового аргумента вместе с поясняющим текстом.
В главном методе командой
Alpha A = new Alpha("Экземпляр A");
A.MyEvent += show;
A.RaiseMyEvent();
Bravo B = new Bravo(); ,
На следующем шаге мы рассмотрим структуры и интерфейсы.