// Создать экземпляр MiniVan на лету.
object obj = Activator.CreateInstance(miniVan);
Console.WriteLine("Created a {0} using late binding!", obj);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Перед запуском нового приложения понадобится вручную скопировать файл CarLibrary.dll
bin\Debug\net5.0, если вы работаете в Visual Studio) данного приложения.На заметку!
Не добавляйте ссылку наCarLibrary.dll в этом примере! Вся суть позднего связывания заключается в попытке создания объекта, который не известен на этапе компиляции.Обратите внимание, что метод Activator.Createlnstance()
System.Object, а не строго типизированный объект MiniVan. Следовательно, если применить к переменной obj операцию точки, то члены класса MiniVan не будут видны. На первый взгляд может показаться, что проблему удастся решить с помощью явного приведения:// Привести к типу MiniVan, чтобы получить доступ к его членам?
// Нет! Компилятор сообщит об ошибке!
object obj = (MiniVan)Activator.CreateInstance(minivan);
Однако из-за того, что в приложение не была добавлена ссылка на сборку CarLibrary.dll
using для импортирования пространства имен CarLibrary нельзя, а значит невозможно и указывать тип MiniVan в операции приведения! Не забывайте, что смысл позднего связывания — создание экземпляров типов, о которых на этапе компиляции ничего не известно. Учитывая сказанное, возникает вопрос: как вызывать методы объекта MiniVan, сохраненного в ссылке на System.Object? Ответ: конечно же, с помощью рефлексии.Вызов методов без параметров
Предположим, что требуется вызвать метод TurboBoost()
MiniVan. Вспомните, что упомянутый метод переводит двигатель в нерабочее состояние и затем отображает окно с соответствующим сообщением. Первый шаг заключается в получении объекта MethodInf о для метода TurboBoost() посредством Туре.GetMethod(). Имея результирующий объект MethodInfо, можно вызвать MiniVan.TurboBoost() с помощью метода Invoke(). Метод MethodInfо.Invoke() требует указания всех параметров, которые подлежат передаче методу, представленному объектом MethodInfо. Параметры задаются в виде массива объектов System.Object (т.к. они могут быть самыми разнообразными сущностями).Поскольку метод TurboBoost()
null (т.е. сообщить, что вызываемый метод не имеет параметров). Обновите метод CreateUsingLateBinding() следующим образом:static void CreateUsingLateBinding(Assembly asm)
{
try
{
// Получить метаданные для типа Minivan.
Type miniVan = asm.GetType("CarLibrary.MiniVan");
// Создать объект MiniVan на лету.
object obj = Activator.CreateInstance(miniVan);
Console.WriteLine($"Created a {obj} using late binding!");
// Получить информацию о TurboBoost.
MethodInfo mi = miniVan.GetMethod("TurboBoost");
// Вызвать метод (null означает отсутствие параметров).
mi.Invoke(obj, null);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Теперь после запуска приложения вы увидите в окне консоли сообщение о том, что двигатель вышел из строя ("Eek! Your engine block exploded!"
Вызов методов с параметрами
Когда позднее связывание нужно применять для вызова метода, ожидающего параметры, аргументы потребуется упаковать в слабо типизированный массив object
Car с радиоприемником был определен следующий метод:public void TurnOnRadio(bool musicOn, MusicMediaEnum mm)
=> MessageBox.Show(musicOn ? $"Jamming {mm}" : "Quiet time...");