Шрифт:
Снова обратите внимание на формат делегата BinaryOp, который может указывать на любой метод, принимающий два целых значения и возвращающий целое значение. Итак, мы создали класс с именем SimpleMath, определяющий два статических метода, которые (как неожиданно) соответствуют шаблону, определенному делегатом BinaryOp.
Чтобы добавить целевой метод в делегат, нужно просто передать имя этою метода конструктору делегата. Тогда вы сможете вызвать указанный член с помощью синтаксической конструкции, подобной прямому вызову функции.
"За кулисами" среда выполнения вызывает сгенерированный компилятором метод Invoke. Вы можете проверить это сами, если откроете компоновочный блок с помощью ildasm.exe и посмотрите на программный код CIL метода Main.
Напомним, что делегаты .NET (в отличие от указателей функций в C) обеспечивают типовую безопасность. Поэтому, если вы попытаетесь передать делегату метод, "не соответствующий шаблону", вы получите сообщение об ошибке компиляции. Например, предположим, что класс SimpleMath определяет еще один метод, носящий имя SquareNumber.
С учетом того, что делегат BinaryOp может указывать только на методы, принимающие два целых значения и возвращающие целое значение, следующий программный метод оказывается некорректным и компилироваться не будет.
Исследование объекта делегата
Добавим в имеющийся пример вспомогательную функцию с именем DisplayDelegateInfo. Она будет выводить имена методов, поддерживаемых поступающим типом, производным от System.Delegate, а также имя класса, определяющего метод. Для этого мы выполним цикл по элементам массива System.Delegate, возвращенного из GetInvocationList, вызывая свойства Target и Method для каждого объекта.
Если изменить метод Main так, чтобы он вызывал этот новый вспомогательный метод, то вы увидите вывод, показанный на рис. 8.3.
Рис. 8.3. Проверка списка вызовов делегата
Обратите внимание на то, что здесь имя типа (SimpleMath) свойством Target не отображается. Причина в том, что наш делегат BinaryOp указывает на статические методы, следовательно, нет объекта, на который нужно ссылаться! Но если изменить методы Add и Subtract так, чтобы они перестали быть статическими, можно создать экземпляр типа SimpleMath и указать методы для вызова так, как показано ниже.