Групповое преобразование методов в C#
Групповое преобразование методов в C#
Еще одной связанной с делегатами и событиями возможностью в C# является так называемое групповое преобразование методов. Эта возможность позволяет регистрировать "просто" имя обработчика событий. Чтобы пояснить это на примере, мы снова рассмотрим тип SimpleMath, уже рассматривавшийся в этой главе выше, но добавим в него новое событие, которому будет назначено имя ComputationFinished.
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, int y) {
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.
![](https://storage.yandexcloud.net/wr4img/167642_306__8.9.png)
Рис. 8.9. Можно извлечь делегат из соответствующего обработчика события
Исходный код. Проект AnonymousMethods размещен в подкаталоге, соответствующем главе 8.