Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp_Prog_Guide.doc
Скачиваний:
16
Добавлен:
16.11.2019
Размер:
6.22 Mб
Скачать

Делегаты

Делегат — это тип, который ссылается на метод. Когда делегату назначается методу, он ведет себя в точности, как этот метод. Метод делегата можно вызывать с параметрами и возвращаемым значением, как и любой другой метод, как показано в примере:

----

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

Примечание.

В контексте перегрузки метода сигнатура метода не содержит возвращаемое значение. Однако в контексте делегатов сигнатура метода содержит возвращаемое значение.

Благодаря возможности ссылаться на метод как на параметр делегаты оптимально подходят для задания функций обратного вызова. Например, алгоритм сортировки можно передать как ссылку на метод, сравнивающий два объекта. Отделение кода сравнения позволяет составить алгоритм в более общем виде.

Общие сведения о делегатах

Делегаты имеют следующие свойства.

  • Делегаты похожи на указатели функций в C++, но являются строго типизированными.

  • Делегаты допускают передачу методов в качестве параметров.

  • Делегаты можно использовать для задания функций обратного вызова.

  • Делегаты можно связывать друг с другом; например, несколько методов можно вызвать по одному событию.

  • Точное соответствие сигнатуры метода и делегата не требуется. Дополнительные сведения см. в разделе Ковариация и контрвариация в делегатах.

  • В C# версии 2.0 представлена концепция анонимных методов, которые позволяют передавать блоки кода в виде параметров вместо использования отдельно определенного метода. В C# 3.0 для краткой записи встроенных блоков кода введены лямбда-выражения. В результате компиляции, как анонимных методов, так и лямбда-выражений (в определенном контексте) получаются типы делегатов. В настоящее время эти функции объединяются под одним названием — анонимные функции. Дополнительные сведения о лямбда-выражениях см. в разделе Анонимные функции.

Using Delegates

A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. The following example declares a delegate named Del that can encapsulate a method that takes a string as an argument and returns void:

public delegate void Del(string message);

A delegate object is normally constructed by providing the name of the method the delegate will wrap, or with an anonymous Method. Once a delegate is instantiated, a method call made to the delegate will be passed by the delegate to that method. The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. This is known as invoking the delegate. An instantiated delegate can be invoked as if it were the wrapped method itself. For example:

// Create a method for a delegate.

public static void DelegateMethod(string message)

{

System.Console.WriteLine(message);

}

// Instantiate the delegate.

Del handler = DelegateMethod;

// Call the delegate.

handler("Hello World");

Delegate types are derived from the Delegate class in the .NET Framework. Delegate types are sealed—they cannot be derived from— and it is not possible to derive custom classes from Delegate. Because the instantiated delegate is an object, it can be passed as a parameter, or assigned to a property. This allows a method to accept a delegate as a parameter, and call the delegate at some later time. This is known as an asynchronous callback, and is a common method of notifying a caller when a long process has completed. When a delegate is used in this fashion, the code using the delegate does not need any knowledge of the implementation of the method being used. The functionality is similar to the encapsulation interfaces provide.