Шрифт:
Обратите внимание на то, что метод Activator.CreateInstance возвращает обобщенный System.Object, а не строго типизированный MiniVan. Поэтому если к переменной obj вы примените операцию, обозначаемую точкой, то не увидите никаких членов типа MiniVan. На первый взгляд, можно предположить, что эта проблема решается с помощью явного преобразования типа, но ведь программа не имеет никаких указаний на то, что MiniVan должен иметь при выборе какие-либо преимущества.
Весь смысл динамической привязки заключается в создании экземпляров объектов, для которых нет статической информации. Но как при этом можно вызвать методы объекта MiniVan, сохраненного в переменной System.Object? Ответ: с помощью отображений.
Вызов методов без параметров
Предположим, что нам нужно вызвать метод TurboBoost типа MiniVan. Вы помните, что этот метод приводит двигатель в "абсолютно нерабочее" состояние и генерирует появление информационного блока сообщения. Первым нашим шагом должно быть получение типа MethodInfо для метода TurboBoost с помощью Type.GetMethod. Получив MethodInfo, мы сможем вызвать Minivan.TurboBoost с помощью Invoke. Для MethodInfo.Invoke необходимо указать все параметры, которые должны быть переданы методу, представленному с помощью MethodInfo. Эти параметры представляются массивом System.Object (поскольку метод может иметь любое число параметров любого типа).
Наш метод TurboBoost не имеет параметров, поэтому для него указывается null (в данном случае это и означает отсутствие параметров у метода). Модифицируйте метод Main так.
После этого вы сможете лицезреть сообщение, подобное показанному на рис. 12.5.
Рис. 12.5. Вызов метода в условиях динамической привязки
Вызов методов с параметрами
Чтобы показать пример динамического вызова метода, имеющего параметры, предположим, что тип MiniVan определяет метод, который называется TellChildToBeQuiet.
Метод TellChildToBeQuiet (приказать ребенку успокоиться) имеет два параметра: строковое представление имени ребенка и целое число, отражающее степень вашего раздражения. При использовании динамического связывания параметры упаковываются в массив объектов System.Object. Для вызова этого нового метода добавьте в свой метод Main следующий программный код.
Выполнив эту программу, вы сможете увидеть четыре блока сообщений, отражающих намерение пристыдить юного Фреда. Надеюсь, что к этому моменту нашего обсуждения вы уже можете видеть взаимосвязь между отображением, динамической загрузкой и динамическим связыванием. Для вас еще может оставаться неясным ответ на вопрос, когда следует использовать указанный подход в приложениях. Завершающий раздел этой главы должен пролить на это свет, но пока что следующей темой нашего рассмотрения будет исследование роли атрибутов .NET.
Исходный код. Проект LateBinding размещен в подкаталоге, соответствующем главе 12.
Программирование с помощью атрибутов
Как сказано в начале этой главы, одной из задач компилятора .NET является генерирование метаданных для всех определяемых типов и для типов, на которые имеются ссылки. Кроме этих стандартных метаданных, содержащихся в каждом компоновочном блоке, платформа .NET дает программисту возможность встроить в компоновочный блок дополнительные метаданные, используя атрибуты. В сущности, атрибуты представляют собой аннотации программного кода, которые могут применяться к заданному типу (классу, интерфейсу, структуре и т.п.), члену (свойству, методу и т.п.), компоновочному блоку или модулю.