Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 206 207 208 209 210 211 212 213 214 ... 407
d5 0a 3a

//   Name: System.Runtime

//   Version: 5.0.0.0

//   Major Version: 0x00000005

//   Minor Version: 0x00000000

//   Build Number: 0x00000000

//   Revision Number: 0x00000000

//   Locale: <null>

//   HashValue Blob:

//   Flags: [none] (00000000)

Документирование строковых литералов

Последний полезный аспект, относящийся к метаданным .NET Core, связан с тем, что все строковые литералы в кодовой базе документируются внутри маркера User Strings:

// User Strings

// -------------------------------------------------------

// 70000001 : (23) L"CarLibrary Version 2.0!"

// 70000031 : (13) L"Quiet time..."

// 7000004d : (11) L"Jamming {0}"

// 70000065 : (32) L"Eek! Your engine block exploded!"

// 700000a7 : (34) L"Ramming speed! Faster is better..."

На заметку! Всегда помните о том, что все строки явным образом документируются в метаданных сборки, как продемонстрировано в представленном выше листинге метаданных. Это может привести к крупным последствиям в плане безопасности, если вы применяете строковые литералы для хранения паролей, номеров кредитных карт или другой конфиденциальной информации.

У вас может возникнуть вопрос о том, каким образом задействовать такую информацию в разрабатываемых приложениях (в лучшем сценарии) или зачем вообще заботиться о метаданных (в худшем сценарии). Чтобы получить ответ, необходимо ознакомиться со службами рефлексии .NET Core. Следует отметить, что полезность рассматриваемых далее тем может стать ясной только ближе к концу главы, а потому наберитесь терпения.

На заметку! В разделе METAINFO вы также найдете несколько маркеров CustomAttribute, которые документируют атрибуты, применяемые внутри кодовой базы. Роль атрибутов .NET Core обсуждается позже в главе.

Понятие рефлексии

В мире .NET Core рефлексией называется процесс обнаружения типов во время выполнения. Службы рефлексии дают возможность получать программно ту же самую информацию о метаданных, которую генерирует утилита ildasm.exe, используя дружественную объектную модель. Например, посредством рефлексии можно извлечь список всех типов, содержащихся внутри заданной сборки *.dll или *.ехе, в том числе методы, поля, свойства и события, которые определены конкретным типом. Можно также динамически получать набор интерфейсов, поддерживаемых заданным типом, параметры метода и другие относящиеся к ним детали (базовые классы, пространства имен, данные манифеста и т.д.).

Как и любое другое пространство имен, System.Reflection (из сборки System.Runtime.dll) содержит набор связанных типов. В табл. 17.1 описаны основные члены System.Reflection, которые необходимо знать.

Чтобы понять, каким образом задействовать пространство имен System.Reflection для программного чтения метаданных .NET Core, сначала следует ознакомиться с классом System.Туре.

Класс System.Туре

В классе System.Туре определены члены, которые могут применяться для исследования метаданных типа, большое количество которых возвращают типы из пространства имен System.Reflection. Например, метод Туре.GetMethods() возвращает массив объектов MethodInfo, метод Type.GetFields() — массив объектов FieldInfo и т.д. Полный перечень членов, доступных в System.Туре, довольно велик, но в табл. 17.2 приведен список избранных членов, поддерживаемых System.Туре (за исчерпывающими сведениями обращайтесь в документацию по .NET Core).

Получение информации о типе с помощью System.Object.GetType()

Экземпляр класса Туре можно получать разнообразными способами. Тем не менее, есть одна вещь, которую делать невозможно — создавать объект Туре напрямую, используя ключевое слово new, т.к. Туре является абстрактным классом. Касательно первого способа вспомните, что в классе System.Object определен метод GetType(), который возвращает экземпляр класса Туре, представляющий метаданные текущего объекта:

// Получить информацию о типе с применением экземпляра 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().

// (Не генерировать исключение, если тип SportsCar не удается найти,

// и игнорировать регистр символов.)

Type t = Type.GetType("CarLibrary.SportsCar", false, true);

В приведенном выше примере обратите внимание на то, что в строке, передаваемой методу GetType(), никак не упоминается сборка, внутри которой содержится интересующий тип. В этом случае делается предположение о том, что тип определен внутри сборки, выполняющейся в текущий момент. Тем не менее, когда необходимо получить метаданные для типа из внешней сборки, строковый параметр форматируется с использованием полностью заданного имени типа, за которым следует запятая и

1 ... 206 207 208 209 210 211 212 213 214 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий