Делегаты

Делегат представляет собой объект, ссылающийся на метод или группу методов. Экземпляр делегата содержит список вызовов, который состоит из одного или более методов, которые называются вызываемыми сущностями. Для экземплярных методов вызываемая сущность содержит ссылку на экземпляр объекта и его метод. Для статических методов вызываемая сущность содержит только метод. Вызов делегата с набором параметров приводит к поочередному вызову всех методов, ссылки на которые добавлены в экземпляр делегата.

Определение делегата состоит из опционального модификатора доступа Public или Friend с последующим ключевым словом Delegate и именем делегата. Далее в круглых скобках опциально могут быть указаны параметры. Метод и делегат являются совместимыми если выполняются оба следующих условия:

Делегаты являются неявно завершёнными и не допускается определение типов, производных от делегатов. Также не допускается определение типов, производных от System.Delegate и не являющихся делегатами.

Создание экземпляра делегата производится путём указания ключевого слова New, после которого указывается наименование делегата и метод, на который будет ссылаться делегат. Расширение списка методов производится в форме delegate += sub, уменьшение списка методов в форме delegate -= sub.

Созданный экземпляр делегата всегда ссылается на один и тот же объект и метод(ы). При комбинировании двух экземпляров делегатов или при удалении одного из другого всегда создается новый экземпляр с собственным списком вызовов, при этом списки вызовов операндов остаются неизменными. При объединении двух непустых делегатов их списки вызовов объединяются в порядке слева направо.

Делегаты выступают в качестве типов при описании событий.

Вызов делегата

Вызов делегата осуществляется путём указания имени созданного экземпляра делегата и набора значений параметров. При вызове непустого делегата содержащего один элемент в списке вызовов производится вызов соответствующего метода со значениями параметров и возврат значения, которое вернул этот метод. Если во время вызова возникла исключительная ситуация, которая не была обработана в самом методе, поиск обработчика исключения продолжается в теле метода, вызвавшего делегат.

Вызов делегата, содержащего более чем один элемент в списке вызовов, производится путем поочередного синхронного вызова методов в списке вызовов. Каждый метод вызывается с набором аргументов, переданным при вызове делегату. Если делегат имеет выходные параметры (Out) или возвращаемое значение, то их конечные значения получаются при вызове последнего метода из списка. Если во время вызова возникла исключительная ситуация, которая не была обработана в самом методе, поиск обработчика исключения продолжается в теле метода, вызвавшего делегат. При этом вызов последующих методов в списке не производится.

Public Delegate UserEventHandler(x, y, z: integer);

Public Class DelegateSample
    
//Событие класса
    Public Event OnUserEvent1: UserEventHandler;

    
Public Constructor UserObject();
    
Begin
        
//Установка обработчиков событий
        //При наступлении события поочередно будут выполнены процедуры Sub1 и Sub2
        OnUserEvent1 := Sub1;
        OnUserEvent1 += Sub2;
    
End Constructor;

    
//Процедуры - обработчики событий
    Sub Sub1(x, y, z: integer);
    
Begin
    
End Sub;

    
Sub Sub2(x, y, z: integer);
    
Begin
    
End Sub;

    
Shared Sub Sub3(x, y, z: integer);
    
Begin
    
End Sub;

    //Процедура создания и вызова экземпляра делегата
    Public Sub RunDelegate(x, y, z: integer);
    
Var
        d1, d2: UserEventHandler;
    
Begin
        
//Создании экземпляра делегата
        d1 := New UserEventHandler(Sub1);
        d1 += Sub2;
        d2 := 
New UserEventHandler(Sub3);
        d1 += d2;
        
//Вызов делегата. При вызове будут выполнены процедуры Sub1, Sub2 и Sub3
        d1(x, y, z);
    
End Sub;
End Class;

См. также:

Руководство по языку Fore.NET