.NET 中的反射

System.Reflection 命名空间中的类与 System.Type 使你能够获取有关加载的程序集和其中定义的类型的信息,如接口和值类型(即结构枚举)。 可以使用反射在运行时创建、调用和访问类型实例。

程序集包含模块、模块包含类型,而类型包含成员。 反射提供封装程序集、模块和类型的对象。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。 然后,可以调用类型的方法或访问其字段和属性。 反射的典型用法如下所示:

  • 使用 Assembly 来定义和加载程序集,加载程序集清单中列出的模块,以及在此程序集中定位一个类型并创建一个它的实例。
  • 使用 Module 发现信息,如包含模块的程序集和模块中的类。 还可以获取所有全局方法或模块上定义的其它特定的非全局方法。
  • 使用 ConstructorInfo 发现信息,如名称、参数、访问修饰符(如 publicprivate)和构造函数的实现详细信息(如 abstractvirtual)。 使用 TypeGetConstructorsGetConstructor 方法来调用特定构造函数。
  • 使用 MethodInfo 发现信息,如名称、返回类型、参数、访问修饰符和方法的实现详细信息(如 abstractvirtual)。 使用 TypeGetMethodsGetMethod 方法来调用特定方法。
  • 使用 FieldInfo 发现信息,如名称、访问修饰符和字段的实现详细信息 (如 static),并获取或设置字段值。
  • 使用 EventInfo 发现信息(如名称、事件处理程序的数据类型、自定义特性、声明类型以及事件的反射的类型),并添加或删除事件处理程序。
  • 使用 PropertyInfo 发现信息(如名称、数据类型、声明类型,反射的类型和属性的只读或可写状态),并获取或设置属性值。
  • 使用 ParameterInfo 发现信息,如参数的名称、数据类型、参数是输入参数还是输出参数以及参数在方法签名中的位置。
  • 当你在 MetadataLoadContext 或仅反射上下文 (.NET Framework) 中工作时使用 CustomAttributeData 发现有关自定义特性的信息。 CustomAttributeData 使你能够检查特性,而无需创建它们的实例。

System.Reflection.Emit 命名空间的类提供一种专用形式的反射,使你能够在运行时生成类型。

还可以使用反射来创建类型浏览器,它使用户能够选择类型,然后查看有关这些类型的信息。

反射还有其它用途。 JScript 等语言的编译器使用反射来构造符号表。 System.Runtime.Serialization 命名空间中的类使用反射来访问数据并确定要保存哪些字段。 System.Runtime.Remoting 命名空间中的类通过序列化间接使用反射。

反射中的运行时类型

反射提供类(如 TypeMethodInfo),用于表示类型、成员、参数和其它代码实体。 但使用反射时,你并不直接使用这些类,其中大部分类均是抽象的(Visual Basic 中为 MustInherit)。 相反,你使用由公共语言运行时 (CLR) 提供的类型。

例如,使用 C# typeof 运算符(Visual Basic 中为 GetType)获取 Type 对象时,该对象实际上是 RuntimeTypeRuntimeType 派生自 Type,并提供所有抽象方法的实现。

这些运行时类是 internal(Visual Basic 中为 Friend)。 它们没有与其基类分开记录,因为它们的行为由基类文档来描述。

参考