//                     (1) ParamToken : Name : x flags: [none]

//                     (2) ParamToken : Name : y flags: [none] //

//     Method #3

//     -------------------------------------------------------

//             MethodName: BeginInvoke

//             ReturnType: Class System.IAsyncResult

//             4 Arguments

//                     Argument #1:  I4

//                     Argument #2:  I4

//                     Argument #3:  Class System.AsyncCallback

//                     Argument #4:  Object

//             4 Parameters

//                     (1) ParamToken : Name : x flags: [none]

//                     (2) ParamToken : Name : y flags: [none]

//                     (3) ParamToken : Name : callback flags: [none]

//                     (4) ParamToken : Name : object flags: [none]

//

//     Method #4

//     -------------------------------------------------------

//             MethodName: EndInvoke

//             ReturnType: I4 (int32)

//             1 Arguments

//                     Argument #1:  Class System.IAsyncResult

//             1 Parameters

//                     (1) ParamToken : Name : result flags: [none]

Как видите, в сгенерированном компилятором классе BinaryOp определены три открытых метода. Главным методом в .NET Core является Invoke(), т.к. он используется для вызова каждого метода, поддерживаемого объектом делегата, в синхронной манере; это означает, что вызывающий код должен ожидать завершения вызова, прежде чем продолжить свою работу. Довольно странно, но синхронный метод Invoke() может не нуждаться в явном вызове внутри вашего кода С#. Вскоре будет показано, что Invoke() вызывается "за кулисами", когда вы применяете соответствующий синтаксис С#.

На заметку! Несмотря на то что методы BeginInvoke() и EndInvoke() генерируются, они не поддерживаются при запуске вашего кода под управлением .NET Core. Это может разочаровывать, поскольку в случае их использования вы получите ошибку не на этапе компиляции, а во время выполнения.

Так благодаря чему же компилятор знает, как определять метод Invoke()? Для понимания процесса ниже приведен код сгенерированного компилятором класса BinaryOp (полужирным курсивом выделены элементы, указанные в определении типа делегата):

sealed class BinaryOp : System.MulticastDelegate

{

  public int Invoke(int x, int y);

...

}

Первым делом обратите внимание, что параметры и возвращаемый тип для метода Invoke() в точности соответствуют определению делегата BinaryOp.

Давайте рассмотрим еще один пример. Предположим, что определен тип делегата, который может указывать на любой метод, возвращающий значение string и принимающий три входных параметра типа System.Boolean:

public delegate string MyDelegate (bool a, bool b, bool c);

На этот раз сгенерированный компилятором класс можно представить так:

sealed class MyDelegate : System.MulticastDelegate

{

  public string Invoke(bool a, bool b, bool c);

...

}

Делегаты могут также "указывать" на методы, которые содержат любое количество параметров out и ref (а также параметры типа массивов, помеченные с помощью ключевого слова params). Пусть имеется следующий тип делегата:

public delegate string MyOtherDelegate(out bool a, ref bool b, int c);

Сигнатура метода Invoke() выглядит вполне ожидаемо.

Перейти на страницу:

Похожие книги