Вход/Регистрация
ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
вернуться

Троелсен Эндрю

Шрифт:

Замечание. Анонимный метод не имеет возможности получить доступ к параметрам ref и out определяющего метода.

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

Резюме

В этой главе был рассмотрен ряд подходов, позволяющих реализовать возможность двухстороннего взаимодействия объектов. Сначала было рассмотрено использование интерфейсов обратного вызова, которые обеспечивают возможность для объекта А вызывать объект В с помощью общего интерфейса. Этот подход не является специфическим для .NET, а может использоваться в любых языках и на любых платформах, допускающих программирование на основе интерфейсов.

Затем было рассмотрено ключевое слово C# delegate, которое используется для непрямого построения классов, производных от System.MulticastDelegate. Как выяснилось, делегат представляет собой объект, хранящий список методов, доступных для вызова. При этом вызовы, могут быть синхронными (они выполняются с помощью метода Invoke) или асинхронными (они выполняются с помощью методов BeginInvoke и EndInvoke). Асинхронная природа типов делегата .NET будет рассмотрена позже.

Ключевое слово C# event при использовании с типом делегата позволяет упростить процесс отправки сообщений событий вызывающим объектам. Как показывает генерируемый CIL-код, модель событий .NET сводит ситуацию к скрытым вызовам типов System.Delegate/System.MulticastDelegate. В этой связи ключевое слово C# event оказывается необязательным и просто экономит время при наборе текста программы.

  • Читать дальше
  • 1
  • ...
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: