Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 86 стр.

UptoLike

этом, если мы знаем их имена, мы можем воспользоваться методами
GetField, GetConstructor, GetMethod, GetProperty и GetNestedType класса
Type. А если мы хотим получить массивы объектов рефлексии, описываю-
щих члены типа, то нам нужно вызвать методы GetFields, GetConstructors,
GetMethods, GetProperties и GetNestedTypes. В следующем примере на эк-
ран выводится список типов, содержащихся в сборке, вместе с сигнатура-
ми их методов:
Assembly assembly = Assembly.LoadFrom(“test.exe”);
Type[] types = assembly.GetTypes();
foreach (Type t in types)
{
Console.WriteLine(“”+t+”:”);
MethodInfo[] methods = t.GetMethods();
foreach (MethodInfo m in methods)
Console.WriteLine(“ “+m);
}
Для каждого метода и конструктора мы можем получить доступ к
массиву объектов рефлексии, описывающих его параметры. Для этого
служит метод GetParameters, объявленный в классах MethodInfo и
ConstructorInfo. Данный метод возвращает массив объектов класса
ParameterInfo:
ParameterInfo[] parms = method.GetParameters();
4.4.2.2. Управление объектами
Кроме чтения метаданных, библиотека рефлексии позволяет созда-
вать экземпляры типов, входящих в обрабатываемую сборку, вызывать ме-
тоды этих типов, читать и изменять значения полей.
Рассмотрим класс TestClass:
class TestClass
{
private int val;
public TestClass() { val = 7; }
protected void print() { Console.WriteLine(val); }
}
В следующем примере мы используем метод Invoke класса MethodInfo
для вызова метода print объекта класса TestClass. Обратите внимание, что
метод print объявлен с модификатором доступа protected.
static void CallMethodDemo()
{
TestClass a = new TestClass();
BindingFlags flags = (BindingFlags)
(BindingFlags.NonPublic | BindingFlags.Instance);
Анализ кода на CIL
159
foreach (Module mod in modules)
{
MethodInfo[] methods = mod.GetMethods();
foreach (MethodInfo met in methods)
Console.WriteLine(met);
}
Особое место в библиотеке рефлексии занимает класс Type, предста-
вляющий типы. Область применения этого класса значительно шире, чем
области применения остальных классов рефлексии, и этот факт отражен в
том обстоятельстве, что класс Type входит в пространство имен System, а
не System.Reflection.
В каждом классе существует унаследованный от класса System.Object
метод GetType, возвращающий экземпляр класса Type, который описывает
этот класс. В следующем примере метод GetType будет использован для ди-
намического определения типа объекта o (так как этот объект представля-
ет собой строку, то на печать будет выведено сообщение «Sytem.String»):
object o = new String(“qwerty”);
Type t = o.GetType();
Console.WriteLine(t);
В C# определен специальный оператор typeof, который возвращает
объект класса Type. Например, если нам нужно получить объект Type,
представляющий тип массива строк, мы можем записать:
Type t = typeof(string[]);
Кроме этого, доступ к информации о типе можно получить, зная имя
этого типа:
1. путем вызова статического метода GetType класса Type:
Type t = Type.GetType(“System.Char”);
2. через объекты классов Assembly или Module, которые соответст-
вуют сборке или модулю, содержащему нужный тип:
Type t = module.GetType(“Class1“);
Type t = assembly.GetType(“Class1“).
Мы также можем воспользоваться методами GetTypes классов
Assembly и Module для получения массива типов, объявленных в сборке или
модуле. В следующем примере на экран выводится список типов, содер-
жащихся в сборке «test.exe»:
Assembly assembly = Assembly.LoadFrom(“test.exe”);
Type[] types = assembly.GetTypes();
foreach (Type t in types)
Console.WriteLine(t);
Имея объект рефлексии, соответствующий некоторому типу, мы
имеем возможность получить доступ к объектам рефлексии, описываю-
щим его поля, конструкторы, методы, свойства и вложенные типы. При
158
CIL и системное программирование в Microsoft .NET
158                         CIL и системное программирование в Microsoft .NET   Анализ кода на CIL                                                   159


     foreach (Module mod in modules)                                            этом, если мы знаем их имена, мы можем воспользоваться методами
     {                                                                          GetField, GetConstructor, GetMethod, GetProperty и GetNestedType класса
       MethodInfo[] methods = mod.GetMethods();                                 Type. А если мы хотим получить массивы объектов рефлексии, описываю-
       foreach (MethodInfo met in methods)                                      щих члены типа, то нам нужно вызвать методы GetFields, GetConstructors,
           Console.WriteLine(met);                                              GetMethods, GetProperties и GetNestedTypes. В следующем примере на эк-
     }                                                                          ран выводится список типов, содержащихся в сборке, вместе с сигнатура-
     Особое место в библиотеке рефлексии занимает класс Type, предста-          ми их методов:
вляющий типы. Область применения этого класса значительно шире, чем                  Assembly assembly = Assembly.LoadFrom(“test.exe”);
области применения остальных классов рефлексии, и этот факт отражен в                Type[] types = assembly.GetTypes();
том обстоятельстве, что класс Type входит в пространство имен System, а              foreach (Type t in types)
не System.Reflection.                                                                {
     В каждом классе существует унаследованный от класса System.Object                  Console.WriteLine(“”+t+”:”);
метод GetType, возвращающий экземпляр класса Type, который описывает                    MethodInfo[] methods = t.GetMethods();
этот класс. В следующем примере метод GetType будет использован для ди-                 foreach (MethodInfo m in methods)
намического определения типа объекта o (так как этот объект представля-                   Console.WriteLine(“ “+m);
ет собой строку, то на печать будет выведено сообщение «Sytem.String»):              }
     object o = new String(“qwerty”);                                                Для каждого метода и конструктора мы можем получить доступ к
     Type t = o.GetType();                                                      массиву объектов рефлексии, описывающих его параметры. Для этого
     Console.WriteLine(t);                                                      служит метод GetParameters, объявленный в классах MethodInfo и
     В C# определен специальный оператор typeof, который возвращает             ConstructorInfo. Данный метод возвращает массив объектов класса
объект класса Type. Например, если нам нужно получить объект Type,              ParameterInfo:
представляющий тип массива строк, мы можем записать:                                 ParameterInfo[] parms = method.GetParameters();
     Type t = typeof(string[]);
     Кроме этого, доступ к информации о типе можно получить, зная имя           4.4.2.2. Управление объектами
этого типа:                                                                           Кроме чтения метаданных, библиотека рефлексии позволяет созда-
        1. путем вызова статического метода GetType класса Type:                вать экземпляры типов, входящих в обрабатываемую сборку, вызывать ме-
              Type t = Type.GetType(“System.Char”);                             тоды этих типов, читать и изменять значения полей.
        2. через объекты классов Assembly или Module, которые соответст-              Рассмотрим класс TestClass:
           вуют сборке или модулю, содержащему нужный тип:                            class TestClass
              • Type t = module.GetType(“Class1“);                                    {
              • Type t = assembly.GetType(“Class1“).                                    private int val;
     Мы также можем воспользоваться методами GetTypes классов                           public TestClass() { val = 7; }
Assembly и Module для получения массива типов, объявленных в сборке или                 protected void print() { Console.WriteLine(val); }
модуле. В следующем примере на экран выводится список типов, содер-                   }
жащихся в сборке «test.exe»:                                                          В следующем примере мы используем метод Invoke класса MethodInfo
     Assembly assembly = Assembly.LoadFrom(“test.exe”);                         для вызова метода print объекта класса TestClass. Обратите внимание, что
     Type[] types = assembly.GetTypes();                                        метод print объявлен с модификатором доступа protected.
     foreach (Type t in types)                                                        static void CallMethodDemo()
       Console.WriteLine(t);                                                          {
     Имея объект рефлексии, соответствующий некоторому типу, мы                         TestClass a = new TestClass();
имеем возможность получить доступ к объектам рефлексии, описываю-                       BindingFlags flags = (BindingFlags)
щим его поля, конструкторы, методы, свойства и вложенные типы. При                        (BindingFlags.NonPublic | BindingFlags.Instance);