Рефлексия обобщенных типов

25

При вызове 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();
        }
    }
}
Пример использования рефлексии типов
Пройди тесты
Лучший чат для C# программистов