Шрифт:
Интервал:
Закладка:
// Получить информацию о типе с применением экземпляра SportsCar.
SportsCar sc = new SportsCar();
Type t = sc.GetType();
Очевидно, что такой подход будет работать, только если подвергаемый рефлексии тип (SportsCar в данном случае) известен на этапе компиляции и в памяти присутствует его экземпляр. С учетом этого ограничения должно быть понятно, почему инструменты вроде ildasm.exe не получают информацию о типе, непосредственно вызывая метод System.Object.GetType() для каждого типа — ведь утилита ildasm.exe не компилировалась вместе с вашими специальными сборками.
Получение информации о типе с помощью typeof()
Следующий способ получения информации о типе предполагает применение операции typeof:
// Получить информацию о типе с использованием операции typeof.
Type t = typeof(SportsCar);
В отличие от метода System.Object.GetType() операция typeof удобна тем, что она не требует предварительного создания экземпляра объекта перед получением информации о типе. Однако кодовой базе по-прежнему должно быть известно об исследуемом типе на этапе компиляции, поскольку typeof ожидает получения строго типизированного имени типа.
Получение информации о типе с помощью System.Туре.GetType()
Для получения информации о типе в более гибкой манере можно вызывать статический метод GetType() класса System.Туре и указывать полностью заданное строковое имя типа, который планируется изучить. При таком подходе знать тип, из которого будут извлекаться метаданные, на этапе компиляции не нужно, т.к. метод Type.GetType() принимает в качестве параметра экземпляр вездесущего класса System.String.
На заметку! Когда речь идет о том, что при вызове метода Туре.GetType() знание типа на этапе компиляции не требуется, имеется в виду тот факт, что данный метод может принимать любое строковое значение (а не строго типизированную переменную). Разумеется, знать имя типа в строковом формате по-прежнему необходимо!
Метод Туре.GetType() перегружен, позволяя указывать два булевских параметра, из которых один управляет тем, должно ли генерироваться исключение, если тип не удается найти, а второй отвечает за то, должен ли учитываться регистр символов в строке. В целях иллюстрации рассмотрим следующий код:
// Получить информацию о типе с использованием статического
// метода Туре.GetType().
<b>// (Не генерировать исключение, если тип SportsCar не удается найти,</b>
<b>// и игнорировать регистр символов.)</b>
Type t = Type.GetType("CarLibrary.SportsCar", false, true);
В приведенном выше примере обратите внимание на то, что в строке, передаваемой методу GetType(), никак не упоминается сборка, внутри которой содержится интересующий тип. В этом случае делается предположение о том, что тип определен внутри сборки, выполняющейся в текущий момент. Тем не менее, когда необходимо получить метаданные для типа из внешней сборки, строковый параметр форматируется с использованием полностью заданного имени типа, за которым следует запятая и дружественное имя сборки (имя сборки без информации о версии), содержащей интересующий тип:
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})// Получить информацию о типе из внешней сборки.
Type t = Type.GetType("CarLibrary.SportsCar, CarLibrary");
Кроме того, в передаваемой методу GetType() строке может быть указан символ "плюс" (+) для обозначения вложенного типа. Пусть необходимо получить информацию о типе перечисления (SpyOptions), вложенного в класс по имени JamesBondCar. В таком случае можно написать следующий код:
// Получить информацию о типе для вложенного перечисления
// внутри текущей сборки.
Type t = Type.GetType("CarLibrary.JamesBondCar+SpyOptions");
Построение специального средства для просмотра метаданных
Чтобы ознакомиться с базовым процессом рефлексии (и выяснить полезность класса System.Туре), создайте новый проект консольного приложения по имени MyTypeViewer. Приложение будет отображать детали методов, свойств, полей и поддерживаемых интерфейсов (в дополнение к другим интересным данным) для любого типа внутри System.Runtime.dll (вспомните, что все приложения .NET Core автоматически получают доступ к этой основной библиотеке классов платформы) или типа внутри самого приложения MyTypeViewer. После создания приложения не забудьте импортировать пространства имен System, System.Reflection и System.Linq:
// Эти пространства имен должны импортироваться для выполнения
// любой рефлексии!
using System;
using System.Linq;
using System.Reflection;
Рефлексия методов
В класс Program будут добавлены статические методы, каждый из которых принимает единственный параметр System.Туре и возвращает void. Первым делом определите метод ListMethods(), который выводит имена методов, определенных во входном типе. Обратите внимание, что Туре.GetMethods() возвращает массив объектов System.Reflection.MethodInfo, по которому можно осуществлять проход с помощью стандартного цикла foreach:
// Отобразить имена методов в типе.
static void ListMethods(Type t)
- Понимание SQL - Мартин Грубер - Базы данных