
- •Введение
- •Сравнение языков С++ и C#
- •Логические выражения
- •Функции для ввода и вывода в языке C#
- •Управление форматом числовых данных:
- •Обработка исключительных ситуаций
- •Методы и модификаторы параметров
- •Неявно типизированные переменные
- •Понятие класса
- •Свойства
- •Индексаторы
- •Одномерные индексаторы
- •Многомерные индексаторы
- •Перегрузка методов
- •Перегрузка знаков операций
- •Наследование
- •Виртуальные функции
- •Работа с файлами
- •Работа с каталогами
- •Абстрактный класс FileSystemInfo
- •Класс DirectoryInfo
- •Сериализация
- •FileSystemWatcher – отслеживание событий, связанных с файлами
- •Обобщения (шаблоны)
- •Интерфейсы
- •Коллекции
- •LINQ
- •Грамматика выражений запросов
- •Синтаксис запросов
- •Проекция и фильтрация
- •Упорядочение
- •Агрегирующие запросы
- •Операции с коллекциями
- •Операция Concat
- •Операция Union
- •Преобразование
- •Объединение последовательностей
- •FirstOrDefault
- •Группировка
- •Групповая адресация
- •Обработка событий
- •Групповое преобразование делегируемых методов
- •Применение методов экземпляра в качестве делегатов
- •Групповая адресация
- •Ковариантность и контравариантность
- •Класс System. Delegate
- •Назначение делегатов
- •Анонимные функции
- •Анонимные методы
- •Передача аргументов анонимному методу
- •Возврат значения из анонимного метода
- •Применение внешних переменных в анонимных методах
- •Лямбда-выражения
- •Лямбда-оператор
- •Одиночные лямбда-выражения
- •Блочные лямбда-выражения
- •События
- •Пример групповой адресации события
- •Применение аксессоров событий
- •Разнообразные возможности событий
- •Применение анонимных методов и лямбда-выражений вместе с событиями
- •Рекомендации по обработке событий в среде .NET Framework
- •Применение делегатов EventHandler<TEventArgs> и EventHandler
- •Практический пример обработки событий
Чернов Э. А. |
- 157 - |
Лекции по языку C# v 2.3 |
не требуется дополнительная информация о событиях. Ниже приведен пример использования делегата EventHandler.
//Использовать встроенный делегат EventHandler.
//Объявить класс, содержащий событие,
class MyEvent
{
public event EventHandler SomeEvent; // использовать делегат EventHandler // Этот метод вызывается для запуска события,
public void OnSomeEvent()
{
if (SomeEvent != null)
SomeEvent(this, EventArgs.Empty);
}
}
class EventDemo7
{
static void Handler(object source, EventArgs arg)
{
Console.WriteLine("Произошло событие");
Console.WriteLine("Источник: " + source);
}
static void Main()
{
MyEvent evt = new MyEvent();
//Добавить обработчик Handler() в цепочку событий. evt.SomeEvent += Handler;
//Запустить событие,
evt.OnSomeEvent();
Console.ReadKey();
}
}
В данном примере параметр типа EventArgs не используется, поэтому в качестве этого параметра передается объект-заполнитель EventArgs . Empty. Результат выполнения кода из данного примера следующий.
Произошло событие Источник: MyEvent
Практический пример обработки событий
События нередко применяются в таких ориентированных на обмен сообщениями средах, как Windows. В подобной среде программа просто ожидает до тех пор, пока не будет получено конкретное сообщение, а затем она предпринимает соответствующее действие. Такая архитектура вполне пригодна для обработки событий средствами С#, поскольку дает возможность создавать обработчики событий для реагирования на различные сообщения и затем просто вызывать обработчик при получении конкретного сообщения. Так, щелчок левой кнопкой мыши может быть связан с событием LButtonClick. При получении сообщения о щелчке левой кнопкой мыши вызывается метод OnLButtonClick (), и об этом событии уведомляются все зарегистрированные обработчики.
Разработка программ для Windows, демонстрирующих такой подход, выходит за рамки этой главы, тем не менее, рассмотрим пример, дающий представление о принципе, по которому действует данный подход. В приведенной ниже программе
Чернов Э. А. |
- 158 - |
Лекции по языку C# v 2.3 |
создается обработчик событий, связанных с нажатием клавиш. Всякий раз, когда на клавиатуре нажимается клавиша, запускается событие KeyPress при вызове метода OnKeyPress (). Следует заметить, что в этой программе формируются .NETсо- вместимые события и что их обработчики предоставляются в лямбда-выражениях.
//Пример обработки событий, связанных с нажатием клавиш на клавиатуре.
//Создать класс, производный от класса EventArgs и
//хранящий символ нажатой клавиши.
class KeyEventArgs: EventArgs
{
public char ch;
}
// Объявить класс события, связанного с нажатием клавиш на клавиатуре, class KeyEvent
{
public event EventHandler<KeyEventArgs> KeyPress; // Этот метод вызывается при нажатии клавиши, public void OnKeyPress(char key)
{
KeyEventArgs k = new KeyEventArgs(); if (KeyPress != null)
{
k.ch = key;
KeyPress(this, k);
}
}
}
// Продемонстрировать обработку события типа KeyEvent. class KeyEventDemo
{
static void Main()
{
KeyEvent kevt = new KeyEvent();
ConsoleKeyInfo key; int count = 0;
//Использовать лямбда-выражение для факта нажатия клавиши. kevt.KeyPress += (sender, e) =>
Console.WriteLine(" Получено сообщение о нажатии клавиши: " + e.ch);
//Использовать лямбда-выражение для подсчета нажатых клавиш. kevt.KeyPress += (sender, e) =>
count++; // count - это внешняя переменная
Console.WriteLine("Введите несколько символов. " + "По завершении введите точку.");
do
{
key = Console.ReadKey(); kevt.OnKeyPress(key.KeyChar);
} while (key.KeyChar != '.');
Console.WriteLine("Было нажато " + count + " клавиш.");
}
}
Вот, например, к какому результату приводит выполнение этой программы.
Чернов Э. А. |
- 159 - |
Лекции по языку C# v 2.3 |
Введите несколько символов. По завершении введите точку. t Получено сообщение о нажатии клавиши: t
е Получено сообщение о нажатии клавиши: е s Получено сообщение о нажатии клавиши: s t Получено сообщение о нажатии клавиши: t
. Получено сообщение о нажатии клавиши: . Было нажато 5 клавиш.
Всамом начале этой программы объявляется класс KeyEventArgs, производный от класса EventArgs и служащий для передачи сообщения о нажатии клавиши обработчику событий. Затем объявляется обобщенный делегат EventHandler, определяющий обработчик событий, связанных с нажатием клавиш. Эти события инкапсулируются в классе KeyEvent, где определяется событие KeyPress.
Вметоде Main () сначала создается объект kevt класса KeyEvent. Затем в цепочку событий kevt. KeyPress добавляется обработчик, предоставляемый лямбдавыражением. В этом обработчике отображается факт каждого нажатия клавиши, как показано ниже.
kevt.KeyPress += (sender, e) =>
Console.WriteLine(" Получено сообщение о нажатии клавиши: " + е.сп);
Далее в цепочку событий kevt. KeyPress добавляется еще один обработчик, предос-
тавляемый лямбда-выражением. В этом обработчике подсчитывается количество нажатых клавиш, как показано ниже.
kevt.KeyPress += (sender, e) =>
count++; // count - это внешняя переменная
Обратите внимание на то, что count является локальной переменной, объявленной в методе Main () и инициализированной нулевым значением.
Далее начинает выполняться цикл, в котором метод kevt.OnKeyPress () вызывается при нажатии клавиши. Об этом событии уведомляются все зарегистрированные обработчики событий. По окончании цикла отображается количество нажатых клавиш. Несмотря на всю свою простоту, данный пример наглядно демонстрирует саму суть обработки событий средствами С#. Аналогичный подход может быть использован и для обработки других событий. Безусловно, в некоторых случаях анонимные обработчики событий могут оказаться непригодными, и тогда придется внедрять именованные методы.