.NET глазами дельфийца. C#
Страница 12. Делегаты и модель обработки событий


 

Делегаты

В 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# и, хотя выглядит относительнообъемным, прозрачно иллюстрирует возможность использования произвольноговнутреннего механизма для хранения ссылок на обработчики и подключенияпроизвольного количества внешних обработчиков.

 
« Предыдущая статья   Следующая статья »