用反射发出定义类型
类型是在动态模块的范围内使用 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)和该操作应用于的权限集。
特性
使用 TypeAttributes.Interface 和 TypeAttributes.Abstract 特性指定接口。
使用 TypeAttributes.Sealed 特性指定具体类(无法扩展的类)。
多个特性确定类型的可见性。 请参见 TypeAttributes 枚举的说明。
如果指定了 TypeAttributes.LayoutSequential,则类加载器按从元数据读取字段的顺序对字段进行布局。 类加载器考虑指定的封装大小,但忽略任何指定的字段偏移量。 元数据保留发出字段定义的顺序。 即使在合并时,元数据也不重新排列字段定义的顺序。 仅当指定了 TypeAttributes.ExplicitLayout 时,加载器才考虑指定的字段偏移量。
已知问题
反射发出不验证实现接口的非抽象类是否已实现在此接口中声明的所有方法。 然而,如果类不实现在一个接口中声明的所有方法,则运行时不加载该类。
虽然 TypeBuilder 从 Type 派生,但 Type 类中定义的某些抽象方法并没有在 TypeBuilder 中完全实现。 这些 TypeBuilder 方法引发 NotSupportedException。 通过使用 Type.GetType 或 Assembly.GetType 检索创建的类型并在检索的类型上反射,可以获得所需的功能。