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


класс System.Reflection.Emit.TypeBuilder

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

TypeBuilder — корневой класс, используемый для управления созданием динамических классов в среде выполнения. Он предоставляет набор подпрограмм, которые используются для определения классов, добавления методов и полей и создания класса внутри модуля. Новое TypeBuilder можно создать из динамического модуля, вызвав ModuleBuilder.DefineType метод, который возвращает TypeBuilder объект.

Эмиссия отражения предоставляет следующие опции для определения типов:

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

Чтобы создать тип массива, тип указателя или тип по ссылке для неполного типа, представленного TypeBuilder объектом, используйте метод MakeArrayType, метод MakePointerType или метод MakeByRefType соответственно.

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

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

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

Атрибуты

Класс TypeBuilder использует TypeAttributes перечисление для дальнейшего указания характеристик создаваемого типа:

  • Интерфейсы задаются с помощью TypeAttributes.Interface атрибутов и TypeAttributes.Abstract атрибутов.
  • Конкретные классы (классы, которые не могут быть расширены) задаются с помощью атрибута TypeAttributes.Sealed .
  • Несколько атрибутов определяют видимость типов. См. описание перечисления TypeAttributes .
  • Если TypeAttributes.SequentialLayout задано, загрузчик класса размещает поля в том порядке, в который они считываются из метаданных. Загрузчик класса учитывает указанный размер упаковки, но игнорирует любые указанные смещения полей. Метаданные сохраняют порядок, в котором выводятся определения полей. Даже при слиянии метаданные не приведут к изменению порядка определений полей. Загрузчик будет учитывать указанные смещения полей, только если TypeAttributes.ExplicitLayout задано.

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

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