Рефлексия обобщенных типов
25C# --- Сборки .NET --- Рефлексия обобщенных типов
При вызове Type.GetType() для получения описаний метаданных обобщенных типов должен обязательно применяться специальный синтаксис в виде символа обратной одинарной кавычки (') со следующим за ним числовым значением, которое представляет количество параметров, поддерживаемое данным типом. Например, чтобы отобразить описание метаданных обобщенного типа System.Collections.Generic.List<T>, приложению потребуется передать следующую строку:
System.Collections.Generic.List '1
Здесь используется числовое значение 1, поскольку List<T> имеет только один параметр. Для применения рефлексии в отношении типа Dictionary<TKey, TValue>, однако, пришлось бы указать значение 2:
System.Collections.Generic.Dictionary '2
Сборка несет в себе сведения о типах классов, структур и прочих элементов данных, которые в ней содержатся. Прикладной интерфейс Reflection API позволяет загрузить сборку, извлечь сведения о ней и получить экземпляры объектов любых открыто доступных в ней типов. Используя этот механизм, программа может выявлять свою среду и использовать те функциональные возможности, которые могут оказаться доступными без явного их определения во время компиляции. Это очень эффективный и привлекательный принцип. Представьте себе, например, программу, которая выполняет роль "браузера типов", отображая типы данных, доступные в системе, или же инструментальное средство разработки, позволяющее визуально составлять программы из различных типов данных, поддерживаемых в системе. А поскольку все сведения о типах могут быть извлечены и проверены, то ограничений на применение рефлексии практически не существует.
Для получения сведений о сборке сначала необходимо создать объект класса Assembly. В классе Assembly открытый конструктор не определяется. Вместо этого объект класса Assembly получается в результате вызова одного из его методов. Так, для загрузки сборки по заданному ее имени служит метод LoadFrom(). Ниже приведена его соответствующая форма:
static Assembly LoadFrom(string файл_сборки)
где файл_сборки-обозначает конкретное имя файла сборки.
Как только будет получен объект класса Assembly, появится возможность обнаружить определенные в нем типы данных, вызвав для него метод GetTypes() в приведенной ниже общей форме:
Type[] GetTypes()
Этот метод возвращает массив типов, содержащихся в сборке.
Для того чтобы продемонстрировать порядок обнаружения типов в сборке, потребуются два исходных файла. Первый файл возьмем из первого раздела данного руководства, где мы создали библиотеку классов fontinfo.dll. Вы можете использовать какую то свою библиотеку классов.
using System;
using System.Reflection;
namespace Reflect
{
class Program
{
static void Main()
{
// Загружаем библиотеку классов
Assembly asm = Assembly.LoadFrom("C:\\myProject\\FontInfo\\fontinfo\\fontinfo.dll");
// Находим типы содержащиеся в fontinfo.dll
Type[] alltypes = asm.GetTypes();
Console.WriteLine("*** Найденые типы ***\n");
foreach (Type t in alltypes)
Console.WriteLine("-> "+t.Name);
Console.WriteLine();
// Выбираем последний класс
Type temp = alltypes[alltypes.Length-1];
Console.WriteLine("Используем класс "+temp.Name + "\n");
// Отображаем сведения о конструкторах
Console.WriteLine("*** Конструкторы ***\n");
ConstructorInfo[] ci = temp.GetConstructors();
foreach (ConstructorInfo c in ci)
{
Console.Write("-> " + c.Name + "(");
// Выводим параметры
ParameterInfo[] p = c.GetParameters();
for (int i = 0; i < p.Length; i++)
{
Console.Write(p[i].ParameterType.Name + " " + p[i].Name);
if (i + 1 < p.Length) Console.Write(", ");
}
Console.Write(")\n\n");
}
Console.ReadLine();
}
}
}
