.NET глазами дельфийца. C# - Делегаты и модель обработки событий
ОГЛАВЛЕНИЕ
Делегаты
В Delphi обработчики событий играют роль делегатов - реальную работу внешнему объекту. Однако из-за того, что Delphi является гибридным языкомпрограммирования, встречаются ситуации, когда семантически эквивалентные задачиреализуются разными способами. Так, например, в класса TList при сортировке используетсяуказатель на функцию сравнения элементов:
type TListSortCompare = function (Item1, Item2: Pointer): Integer;
procedure Sort(Compare: TListSortCompare);
Т.е. на самом деле задача сравнения элементов списка также функции, внешней по отношению к объекту TList.
Такая семантическая неоднозначность отнюдь не упрощаетпрограммирование.
В C# реализован более общий и однозначный подход - делегаты:
delegate void SimpleDelegate();
class Test {
static void F() {
System.Console.WriteLine("Test.F");
}
static void Main() {
SimpleDelegate d = new SimpleDelegate(F);
d();
}
}
Причем в качестве реализации делегата может выступать какстатический, так и обычный метод.
Возможность реализации модели обработки событий
Хотя по умолчанию в C# компоненты реализуют схему подключенияобработчиков событий , при необходимости может бытьреализована модель . Основа такой возможности заключается втом, что в качестве обработчиков событий используются делегаты, а ихподключение к компоненту реализуется с помощью перегружаемого метода:
class Control: Component {
// Unique keys for events
static readonly object mouseDownEventKey = new object();
static readonly object mouseUpEventKey = new object();
// Return event handler associated with key
protected delegate GetEventHandler(object key) {...}
// Add event handler associated with key
protected void AddEventHandler(object key, Delegate handler) {...}
// Remove event handler associated with key
protected void RemoveEventHandler(object key, Delegate handler) {...}
// MouseDown event
public event MouseEventHandler MouseDown {
add { AddEventHandler(mouseDownEventKey, value); }
remove { RemoveEventHandler(mouseDownEventKey, value); }
}
// MouseUp event
public event MouseEventHandler MouseUp {
add { AddEventHandler(mouseUpEventKey, value); }
remove { RemoveEventHandler(mouseUpEventKey, value); }
}
}
Приведенный код взят из спецификации C# и, хотя выглядит относительнообъемным, прозрачно иллюстрирует возможность использования произвольноговнутреннего механизма для хранения ссылок на обработчики и подключенияпроизвольного количества внешних обработчиков.