Bog'liq CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C
Глава.23 .Загрузка.сборок.и.отражение
// Создание экземпляра (dynamic нельзя использовать для вызова конструктора)
Object[] args = new Object[] { 12 }; // Аргументы конструктора
Console.WriteLine("x before constructor called: " + args[0]);
dynamic obj = Activator.CreateInstance(t, args);
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
// Чтение и запись поля
try {
obj.m_someField = 5;
Int32 v = (Int32)obj.m_someField;
Console.WriteLine("someField: " + v);
}
catch (RuntimeBinderException e) {
// Получает управление, потому что поле является приватным
Console.WriteLine("Failed to access field: " + e.Message);
}
// Вызов метода
String s = (String)obj.ToString();
Console.WriteLine("ToString: " + s);
// Чтение и запись свойства
try {
obj.SomeProp = 0;
}
catch (ArgumentOutOfRangeException) {
Console.WriteLine("Property set catch.");
}
obj.SomeProp = 2;
Int32 val = (Int32)obj.SomeProp;
Console.WriteLine("SomeProp: " + val);
// Добавление и удаление делегата для события
obj.SomeEvent += new EventHandler(EventCallback);
obj.SomeEvent = new EventHandler(EventCallback);
}
}
internal static class ReflectionExtensions {
// Метод расширения, упрощающий синтаксис создания делегата
public static TDelegate CreateDelegate
(this MethodInfo mi,
Object target = null) {
return (TDelegate)(Object)mi.CreateDelegate(typeof(TDelegate), target);
}
}
Если построить и запустить этот код, будет выведен следующий результат:
BindToMemberThenInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
663 Нахождение.членов.типа.путем.отражения
someField: 33
ToString: 33
Property set catch.
SomeProp: 2
BindToMemberCreateDelegateToMemberThenInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
ToString: 0
Property set catch.
SomeProp: 2
UseDynamicToBindAndInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
Failed to access field: 'SomeType.m_someField' is inaccessible due to
its protection level
ToString: 0
Property set catch.
SomeProp: 2
Обратите внимание: в единственном параметре конструктора
SomeType
по ссылке
передается
Int32
. В представленном коде показано, как вызвать этот конструктор
и как после завершения конструктора проверить модифицированное значение
Int32
.
Далее в начале метода
BindToMemberThenInvokeTheMember
присутствует вызов ме-
тода
GetType
типа
Type
, которому передается строка
"System.Int32&"
. Амперсанд
(
&
) в строке обозначает параметр, передаваемый по ссылке. Это предусмотрено
нотацией Бэкуса–Наура для записи имен типов (подробнее о ней см. документацию
на FCL). В коде также показано, как добиться того же результата с использованием
метода
MakeByRefType
класса
Type
.