反射
1、定义
反射提供描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。
在 .cs 文件顶部添加 using System;
和 using System.Reflection;
。
C# 关键字 protected
和 internal
在中间语言 (IL) 中没有任何意义,且不会用于反射 API 中。 在 IL 中对应的术语为“系列”和“程序集”。 若要标识 internal
使用反射的方法,请使用 IsAssembly 属性。 若要标识 protected internal
方法,请使用 IsFamilyOrAssembly。
2、使用场景
反射在以下情况下很有用:
- 需要访问程序元数据中的特性时。 有关详细信息,请参阅检索存储在特性中的信息。
- 检查和实例化程序集中的类型。
- 在运行时构建新类型。 使用 System.Reflection.Emit 中的类。
- 执行后期绑定,访问在运行时创建的类型上的方法。 请参阅主题 “动态加载和使用类型”。
3、用法
程序集包含模块、模块包含类型,而类型包含成员。 反射提供封装程序集、模块和类型的对象。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。 然后,可以调用类型的方法或访问其字段和属性。 反射的典型用法如下所示:
-
使用 Assembly 来定义和加载程序集,加载程序集清单中列出的模块,以及在此程序集中定位一个类型并创建一个它的实例。
-
使用 Module 发现信息,如包含模块的程序集和模块中的类。 还可以获取所有全局方法或模块上定义的其它特定的非全局方法。
-
使用 ConstructorInfo 发现信息,如名称、参数、访问修饰符(如
public
或private
)和构造函数的实现详细信息(如abstract
或virtual
)。 使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定构造函数。 -
使用 MethodInfo 发现信息,如名称、返回类型、参数、访问修饰符(如
public
或private
)和方法的实现详细信息(如abstract
或virtual
)。 使用 Type 的 GetMethods 或 GetMethod 方法来调用特定方法。 -
使用 FieldInfo 发现信息,如名称、访问修饰符(如
public
或private
)和一个字段的实现详细信息 (如static
);并获取或设置字段值。 -
使用 EventInfo 发现信息(如名称、事件处理程序的数据类型、自定义特性、声明类型以及事件的反射的类型),并添加或删除事件处理程序。
-
使用 PropertyInfo 发现信息(如名称、数据类型、声明类型,反射的类型和属性的只读或可写状态),并获取或设置属性值。
-
使用 ParameterInfo 发现信息,如参数的名称、数据类型、参数是输入参数还是输出参数以及参数在方法签名中的位置。
-
使用 CustomAttributeData 在于应用程序域的仅反射上下文中工作时发现有关自定义特性的信息。 CustomAttributeData 使你能够检查特性,而无需创建它们的实例。 System.Reflection.Emit 命名空间的类提供一种专用形式的反射,使你能够在运行时生成类型。
还可以使用反射来创建称为类型浏览器的应用程序,它使用户能够选择类型,然后查看有关这些类型的信息。
反射还有其它用途。 JScript 等语言的编译器使用反射来构造符号表。 System.Runtime.Serialization 命名空间中的类使用反射来访问数据并确定要保存哪些字段。 System.Runtime.Remoting 命名空间中的类通过序列化间接使用反射。
4、补充
具体参见: