.NET Core 实战 [No.306~312] 反射
反射技术可以在应用程序运行阶段对程序进行解析,包括获取程序集中的类型、类型的成员列表、参数列表等信息,还可以创建类型实例或调用类型成员。
与反射有关的类型都位于 System.Reflection 命名空间下。
1. Assembly
提供了一系列加载程序的静态方法,最常用的是 LoadFrom 静态方法,通过 dll 文件加载程序集,返回值是一个 Assembly
实例。
Assembly ass = Assembly.LoadFrom("TestLib.dll");
通过 Assembly
实例的属性可以获取程序集的一些基本信息,通过 GetTypes 方法可以获取该程序集的类型列表,GetType 方法可以获取指定的类型。
Type[] types = ass.GetTypes();
Type testType = ass.GetType("Test");
2. Type
Type
类型也提供一些静态方法用以获取类型,如 GetType 方法。
获取到类型实例之后,可以通过如下方法获取类型的成员:
- GetMethods、GetMethod:获取方法(
MethodInfo
)。 - GetProperties、GetProperty:获取属性(
PropertyInfo
)。 - GetEvents、GetEvent:获取事件(
EventInfo
)。 - GetConstructors、GetConstructor:获取构造函数(
ConstructorInfo
)。 - GetFields、GetField:获取字段(
FieldInfo
)。 - GetMembers、GetMember:获取以上所有类型的成员(
MemberInfo
)。
上述方法默认仅获取公共成员,若要获取非公有成员,可以通过调用带 BindingFlags
枚举参数的对应方法。比如若要获取静态方法,可以将参数 bindingAttr 设置为 BindingFlags.Static 。
3. MethodInfo
MethodInfo
类封装了常规方法(不包括构造函数)的相关信息。从上一节可以知道通过 GetMethods、GetMethod 方法可以获取到 MethodInfo
实例。
常用方法如下:
GetParameters:获取方法的参数列表信息。
Invoke:Invoke 位于
MethodInfo
的基类MethodBase
类中,用于执行当前方法。Invoke 有两个重载,常用的是下面这个:obj 为运行当前方法的实例,parameters 为方法的参数。
csharppublic object Invoke(object obj, object[] parameters);
调用静态方法时,由于没有对应的实例,obj 应传空值 null 。
4. ConstructorInfo
ConstructorInfo
类封装了构造函数的相关信息,同 MethodInfo
一样也继承自 MethodBase
。
通过 Type
类的 GetConstructors、GetConstructor 可以获取到构造函数的实例。需要注意的是由于 GetConstructor 没有无参的重载,所以获取无参的构造函数时需要传 Type.EmptyTypes 进去。
ConstructorInfo constr = testType.GetConstructor(Type.EmptyTypes);
调用构造函数方法时也是通过 Invoke 方法。
public object Invoke(object[] parameters);
调用无参构造函数时参数为 null。
object instance = constr.Invoke(null);
5. Activator
Activator
类仅有一个静态方法 CreateInstance,用于创建类型的实例,但该方法有多个重载,常用的是如下两个版本。
调用类型的无参构造函数创建实例:
public static object CreateInstance(Type type);
调用类型的带参数的构造函数创建实例:
public static object CreateInstance(Type type, params object[] args);
下面是调用无参构造函数的示例:
object instance = Activator.CreateInstance(testType);
6. CustomAttribute
CustomAttributeExtensions
类对如下类型提供了 GetCustomAttribute、 GetCustomAttributes 和 IsDefined 扩展方法。
ParameterInfo
Assembly
MemberInfo
Module
ParameterInfo
在上面几节提到的几种成员类型(MethodInfo
、PropertyInfo
、EventInfo
、ConstructorInfo
、FieldInfo
)都是 MemberInfo
的派生类。
上面三个扩展方法中 GetCustomAttribute 和 GetCustomAttributes 方法用于获取成员上应用的特性(Attribute)。示例如下:
DataContractAttribute dataContractAttribute = testType.GetCustomAttribute<DataContractAttribute>();
Console.WriteLine($"类型 {testType.Name} 的数据协定名是:{dataContractAttribute.Name}");
参考:《.NET Core 实战:手把手教你掌握 380 个精彩案例》 -- 周家安 著