Поделиться через


Определение типа с помощью порождения отражения

Обновлен: Ноябрь 2007

Типы определяются в области действия динамического модуля при помощи метода ModuleBuilder.DefineType. DefineType возвращает TypeBuilder. В этом разделе имя типа всегда представляет собой полный путь, включающий пространство имен. Например, если имя типа Aaa.Bbb.Ccc, считается, что Aaa.Bbb — это пространство имен.

Порождение отражения предоставляет следующие варианты определения типов.

  • Определение класса или интерфейса с заданным именем.

  • Определение класса или интерфейса с заданным именем и атрибутами.

  • Определение класса с заданным именем, атрибутов и базового класса.

  • Определение класса с заданным именем, атрибутов, базового класса и набора интерфейсов, реализуемых данным классом.

  • Определение класса с заданным именем, атрибутов, базового класса и размера уплотнения.

  • Определение класса с заданным именем, атрибутов, базового класса и размера класса в целом.

  • Определение класса с заданным именем, атрибутов, базового класса, размера уплотнения и размера класса в целом.

Перед использованием типа необходимо вызвать метод TypeBuilder.CreateType. CreateType завершает создание типа. Вслед за вызовом CreateType вызывающий объект может создать экземпляр типа (с помощью метода Activator.CreateInstance) и вызвать элементы типа (с помощью метода Type.InvokeMember). Вызов методов, изменяющих реализацию данного типа, после вызова CreateType, вызовет ошибку. Например, общеязыковая среда выполнения генерирует исключение, если вызывающий объект пытается добавить в тип новые элементы.

Средство инициализации класса создается с помощью метода TypeBuilder.DefineTypeInitializer. DefineTypeInitializer возвращает ConstructorBuilder.

Вложенные типы определяются с помощью одного из методов TypeBuilder.DefineNestedType.

Метод TypeBuilder.AddDeclarativeSecurity добавляет декларативную безопасность в создаваемый тип. AddDeclarativeSecurity можно вызывать несколько раз, задавая при каждом вызове действие по обеспечению безопасности (такие как Demand, Assert, Deny) и устанавливая разрешения, к которым эти действия применяются.

Атрибуты

  • Интерфейсы описываются с использованием атрибутов TTypeAttributes.Interface и TypeAttributes.Abstract .

  • Закрытые классы (классы, которые не могут быть расширены) задаются с помощью атрибута TypeAttributes.Sealed.

  • Несколько атрибутов определяют видимость типа. См. описание перечисления TypeAttributes.

  • Если задан TypeAttributes.LayoutSequential, загрузчик класса размещает поля в том порядке, в котором они считываются из метаданных. Загрузчик класса учитывает заданный размер записи, но не обрабатывает любые заданные смещения полей. Метаданные сохраняют порядок, в котором происходил выпуск определений полей. Даже при объединении метаданные не будут изменять порядок определений полей. Загрузчик будет принимать заданные смещения полей, только если задан TypeAttributes.ExplicitLayout.

Известные проблемы

  • Порождение отражения не проверяет, реализовал ли неабстрактный класс, реализующий интерфейс, все методы, объявленные в интерфейсе. Однако если этот класс не реализовал все методы, объявленные в интерфейсе, среда выполнения этот класс не загружает.

  • Хотя TypeBuilder является производным от Type, некоторые из абстрактных методов, определенных в классе Type, не полностью реализованы в TypeBuilder. Эти методы TypeBuilder создают исключение NotSupportedException. Необходимая функциональность может быть достигнута путем получения созданного типа с помощью методов Type.GetType или Assembly.GetType и отражения полученного типа.

См. также

Другие ресурсы

Использование порожденного отражения