Один з найбільш сучасних підходів до побудови додатків - підхід, заснований на генерації і подальшій обробці подій.
Подія - це перехід об'єкта з одного стану в інший. Наприклад, натискання клавіші, пересування курсора миші, зміна властивостей якогось об'єкта
Найпростіше подія - це подія, що повідомляє про початок або про завершення деякої процедури.
Події генеруються у відповідь на дії користувача. Це може бути клацання користувачем по кнопці, введення даних в текстове поле, і т.д.
Подія може бути згенеровано і без взаємодії з користувачем, наприклад, при виконанні деякого методу.
Реакція програми на подію проявляється у виконанні деяких дій. Для цього існують обробники подій - методи, які безпосередньо виконує дії.
При виникненні одного і того ж події, для об'єктів різних класів можуть виконуватися різні дії (викликатися різні обробники).
Наприклад, подія «Дзвінок». Реакція на цю подію:
Як же програма дізнається, що подія відбулася, і які обробники цієї події в різних класах потрібно викликати?
Тому є щось, що з'єднує події і обробники. Це підписка на події. При підписці на події вказується, в якому класі, які обробники повинні виконуватися у відповідь на виникнення події.
Для нашого прикладу, є дві підписки на подію «Дзвінок»:
Від події можна і відписатися. При цьому подія відбувається, але відповідний обробник не виконується.
Делегат це клас. Об'єкти цього класу це прототипи функцій, тобто функцій з певною сигнатурою.
Сигнатура функції - це поєднання назви типу, який функція повертає, плюс назва типів входять параметрів (в порядку проходження).
При описі змінної типу делегат вказується ключове слово delegate, а також функція, сигнатура якої збігається з типом делегата. Після цього делегат можна використовувати для виклику зазначеної функції.
Даний делегат Del може представляти будь-яку функцію типу void без значення, що повертається і з одним параметром типу string:
public delegate void Del(string message); |
---|
Даний делегат MyDel може представляти будь-яку функцію типу void без значення, що повертається і без параметрів:
public delegate void MyDel (); |
---|
Даний делегат Ddel може представляти будь-яку функцію типу void без значення, що повертається і з двома параметрами: перший типу int, другий типу double.
public delegate void Ddel (int i, double j); |
---|
делегат змінна = new делегат (об'ект.метод); |
---|
event делегат подія; |
---|
Щоб згенерувати подія, вказується ім'я події, а потім в круглих дужках через кому перераховуються параметри події.
Перш ніж порушувати подія, рекомендується перевірити, чи не дорівнює чи null змінна, що описує подію.
Для підписки на подію для будь-якого об'єкта використовується оператор + =, після якого за допомогою ключового слова new викликається конструктор делегата, в якості параметра якого вказується ім'я методу, що представляє із себе обробник події.
об'ект1.собитіе + = new делегат (об'ект2.метод); |
---|
КлассІліОб'ект.ІмяСобития + = Класс або Об'ект Чий Метод повинен Запуститися. Метод, що Підходить По Сігнатуре |
Ніяких скобочек після методу! Ми ж не викликаємо його, а просто вказуємо його назву.
Клас або об'єкт: вказуємо клас, якщо подія статичну, і об'єкт, якщо об'єкт був створений. У нашому прикладі всі три об'єкти створені, тому вказуємо об'єкт.
Тепер залишилося запустити метод Count класу ClassCounter і почекати, поки i стане рівним 7.
Як тільки i = 7, виникне подія onCount по делегатуMethodContainer, який (в свою чергу) запустить методи Message (), які були підписані на подію.
Результат:
Внесемо деякі зміни.
Результат:
Ще раз порядок написання коду програми: