Групповое преобразование методов в 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.

Рис. 8.9. Можно извлечь делегат из соответствующего обработчика события

Исходный код. Проект AnonymousMethods размещен в подкаталоге, соответствующем главе 8.