Замечание.
Анонимный метод не имеет возможности получить доступ к параметрам ref и out определяющего метода.Групповое преобразование методов в C#
Еще одной связанной с делегатами и событиями возможностью в C# является так называемое
public class SimpleMath {
// Здесь мы не утруждаем себя созданием
// производного типа System.EventArgs.
public delegate void MathMessage(string msg);
public event MathMessage ComputationFinished;
public int Add(int x, int y) {
ComputationFinished("Сложение выполнено.");
return х + y;
}
public int Subtract(int x
ComputationFinished("Вычитание выполнено.");
return x – у;
}
}
Если не использовать синтаксис анонимных методов, то мы должны обработать событие ComputationComplete так, как показано ниже.
class Program {
static void Main(string[] args) {
SimpleMath m = new SimpleMath();
m.ComputationFinished += new SimpleMath.MathMessage(ComputationFinishedHandler);
Console.WriteLine("10 + 10 равно {0}", m.Add(10, 10));
Console.ReadLine();
}
static void ComputationFinishedHandler(string msg) { Console.WriteLine(msg); }
}
Но можно зарегистрировать программу обработки событий для конкретного события и так, как показано ниже (в остальном программный код изменений не претерпевает).
m.ComputationFinished += ComputationFinishedHandler
Обратите внимание на то, что мы не создаем непосредственно соответствующий тип делегата, а просто указываем метод, который соответствует ожидаемой сигнатуре делегата (в данном случае это метод, не возвращающий ничего и получающий один объект типа System.String). Ясно, что компилятор C# при этом должен обеспечить типовую безопасность. Если метод ComputationFinishedHandler() не получает System.String и не возвращает void, то вы получите сообщение об ошибке компиляции.
Можно и явно конвертировать обработчик события в экземпляр соответствующего делегата. Это может оказаться полезным тогда, когда нужно получить соответствующий делегат, использующий заранее определенный метод. Например:
// .NET 2.0 допускает преобразование обработчиков событий
// в соответствующие делегаты.
SimpleMath.MathMessage mmDelegate = (SimpleMath.MathMessage)ComputationFinishedHandler;
Console.WriteLine(mmDelegate.Method);
Если выполнить этот программный код, то заключительный оператор Console.WriteLine() напечатает сигнатуру ComputationFinishedHandler, как показано на рис. 8.9.
Рис. 8.9. Можно извлечь делегат из соответствующего обработчика события
Исходный код
. Проект AnonymousMethods размещен в подкаталоге, соответствующем главе 8.Резюме
В этой главе был рассмотрен ряд подходов, позволяющих реализовать возможность двухстороннего взаимодействия объектов. Сначала было рассмотрено использование
Затем было рассмотрено ключевое слово C# delegate, которое используется для непрямого построения классов, производных от System.MulticastDelegate. Как выяснилось, делегат представляет собой объект, хранящий список методов, доступных для вызова. При этом вызовы, могут быть синхронными (они выполняются с помощью метода Invoke()) или асинхронными (они выполняются с помощью методов BeginInvoke() и EndInvoke()). Асинхронная природа типов делегата .NET будет рассмотрена позже.