Наш метод TurboBoost() не имеет параметров, поэтому для него указывается null (в данном случае это и означает отсутствие параметров у метода). Модифицируйте метод Main() так.
static void Main(string[] args) {
// Попытка загрузить локальную копию CarLibrary.
...
// Получение типа MiniVan.
Type miтiVan = a.GetType("CarLibrary.MiniVan");
// Динамическое создание MiniVan.
object obj = Activator.CreateInstance(miniVan);
// Получение информации о TurboBoost.
MethodInfo mi = miniVan.GetMethod("TurboBoost");
// Вызов метода ('null' означает отсутствие параметров) .
mi.Invoke(obj, null);
}
После этого вы сможете лицезреть сообщение, подобное показанному на рис. 12.5.
Рис. 12.5. Вызов метода в условиях динамической привязки
Вызов методов с параметрами
Чтобы показать пример динамического вызова метода, имеющего параметры, предположим, что тип MiniVan определяет метод, который называется TellChildToBeQuiet().
// Усмирение вопящих…
public void TellChildToBeQuiet(string kidName, int shameIntensity) {
for (int i = 0; i ‹ shameIntensity; i++)
MessageBox.Show("Потише, {0}!!", kidName);
}
Метод TellChildToBeQuiet() (приказать ребенку успокоиться) имеет два параметра: строковое представление имени ребенка и целое число, отражающее степень вашего раздражения. При использовании динамического связывания параметры упаковываются в массив объектов System.Object. Для вызова этого нового метода добавьте в свой метод Main() следующий программный код.
// Динамический вызов метода с параметрами.
object[] paramArray = new object[2];
paramArray[0] = "Фред"; // Имя ребенка.
paramArray[1] = 4; // Степень досады.
mi = miniVan.GetMethod("TellChildToBeQuiet");
mi.Invoke(obj, paramArray);
Выполнив эту программу, вы сможете увидеть четыре блока сообщений, отражающих намерение пристыдить юного Фреда. Надеюсь, что к этому моменту нашего обсуждения вы уже можете видеть взаимосвязь между отображением, динамической загрузкой и динамическим связыванием. Для вас еще может оставаться неясным ответ на вопрос,
Исходный код. Проект LateBinding размещен в подкаталоге, соответствующем главе 12.
Программирование с помощью атрибутов
Как сказано в начале этой главы, одной из задач компилятора .NET является генерирование метаданных для всех определяемых типов и для типов, на которые имеются ссылки. Кроме этих стандартных метаданных, содержащихся в каждом компоновочном блоке, платформа .NET дает программисту возможность встроить в компоновочный блок дополнительные метаданные, используя
Идея аннотирования программного кода с помощью атрибутов не нова. Множество встроенных атрибутов предлагает COM IDL (Interface Definition Language – язык описания интерфейсов), что позволяет разработчику описывать типы COM-сервера. Однако атрибуты COM представляют собой, по сути, лишь набор ключевых слов. Если перед разработчиком COM возникает задача создания пользовательских атрибутов, то эта задача оказывается вполне разрешимой, но ссылаться на такой атрибут в программном коде придется с помощью 128-разрядного номера (GUID), а это, в лучшем случае, слишком обременительно.
В отличие от атрибутов COM IDL (которые, напомним, являются просто ключевыми словами), атрибуты .NET являются типами класса, расширяющими абстрактный базовый класс System.Attribute. При исследовании пространств имен .NET вы можете обнаружить множество встроенных атрибутов, которые можно использовать в приложениях. К тому же вы можете строить свои пользовательские атрибуты, чтобы затем корректировать поведение своих типов с помощью создания новых типов, производных от Attribute.