【.NET Core】反射(Reflection)详解(一)

一、什么是反射

Reflection(反射)是动态获取运行时类型信息的一种方式。.NET的应用程序由几个部分组成:程序集(Assembly)、模块(Module)、类型(Class)组成,而反射提供了一种编程方式。能让程序员可以在程序运行期获得这几个组成部分的相关信息。

二、Assembly类

Assembly表示一个程序集,它是一个可重用、无版本冲突且可自我描述的公共语言运行时应用程序构建基块。

Assembly使用类加载程序集,浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类的实例。

如要获取表示当前加载到应用程序集的Assembly数组。可以使用AppDomain.GetAssemblies方法。

下面介绍Assembly常用的属性和方法:

2.1 LoadFile

加载指定路径上的程序集文件的内容。

Assembly assembly = Assembly.LoadFile("D:\\DLL\\GoyeerClassLoad.dll");

2.2 Load

  • Assembly.Load(AssemblyName):在给定程序集的AssemblyName的情况下,加载程序集。
  • Assembly.Load(Byte[]):加载带有基本通用对象文件格式(COFF)的映像的程序集,该映像包含已发出的程序集。此程序集将会加载到调用方的应用程序域中。
  • Assembly.Load(Byte[],Byte[]):加载带有基本通用对象文件(COFF)的映射的程序集,此映像包含一个已发出的程序集,并且还可以选择包含程序集的符号。此程序集将会加载到调用方的应用程序域中。
  • Assembly.Load(String):用指定的名称加载程序集。
Assembly assemblyLoad = Assembly.Load("AwinicClassLoad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");

2.3 LoadFrom(String)

已知程序集的文件名或路径,加载程序集。

Assembly assemblyForm = Assembly.LoadFrom("D:\\DLL\\AwinicClassLoad.dll");

2.4 GetName()

此方法获取此程序集的AssemblyName。

 AssemblyName assemblyName=  assembly.GetName();

2.5 GetModules()

获取作为此程序集的一部分的所有模块。

Module[] modules = assembly.GetModules();

2.6 GetModule(String)

获取此程序集加载指定的清单资源。

Module[] modules = assembly.GetModules("goyeer.StringHelper");

2.7 GetTypes()

获取程序集中定义的所有类型

Type[] types  = assembly.GetTypes();

2.8 GetType(String,Boolean,Boolean)

获取程序集实例中具有指定名称的Type对象,并选择在找不到该类型是引发异常

//获取当前实例的Type
Type type = assembly.GetType();
//获取程序集实例中具有指定名称的Type对象
Type type1 = assembly.GetType("GoyeerLib.StringHelper");
//获取程序集实例中具有指定名称的Type对象,并选择在找不到该类型时引发异常
Type type2 = assembly.GetType("GoyeerLib.StringHelper",false);
//获取程序集实例中具有指定名称的Type对象,带有忽略大小写和在找不到该类型时引发异常的选项
Type type3 = assembly.GetType("GoyeerLib.StringHelper",false,false);

三、Module 类

模块是可移植的可执行文件,一个DLL或EXE,由一个或多个类和接口组成。单个模块可包含多个命名空间,而一个命名空间可跨越多个模块。一个可部署的程序集是有一个或多个模块组成。在反射中,我们可以通过Assembly程序集,获取对应程序集中的某一个指定模块或所有的模块。下面我们将介绍Model类中常用的属性及方法。

3.1 FilterTypeName

Module中的一个字段,该对象是根据名称筛选在此模块中定义的类型列表。此字段区分大小写且为只读。

Type[] tArray = myModule.FindTypes(Module.FilterTypeName, "My*");

3.2 FilterTypeNameIgnoreCase

Module中的一个字段,一个TypeFilter对象,该对象根据名称筛选在此模块中定义的类型列表。此字段不区分大小写且为只读。

3.3 Assembly

Module的属性,为此Module实例获取适当的Assembly

Module myModule = moduleArray[0];
Assembly myAssembly = myModule.Assembly;

3.4 FullyQualifiedName

Module的属性,获取表示此模块的完全限定名和路径的字符串。

Module myModule = moduleArray[0];
string fullName = myModule.FullyQualifiedName

3.5 ModuleVersionId

获取可用于区分模块的两个版本的全局唯一标识符(UUID)。可用于区分模块的两个版本的Guid

Module myModule = modules[0];
Guid versionId=  myModule.GetModuleVersionId();

3.6 Name

获取String,它表示移除了路径的模块名

Module myModule = modules[0];
string name=  myModule.Name;

显示结果和FullyQualifiedName区别如下显示内容

name=GoyeerClassLoad.dll;
FullyQualifiedName=D:\Office\Debug\GoyeerClassLoad.dll

3.6 ScopeName

获取表示模块名称的字符串如Name

3.7 Equals(Object)

确定此模块和指定的对象是否相等。

3.7 FindTypes(TypeFilter,Object)

返回给定筛选器和筛选条件接受的类数组。

Module myModule = moduleArray[0];
Type[] tArray;
tArray = myModule.FindTypes(Module.FilterTypeName, "My*");

3.8 GetCustomAttributes方法

返回模块自定义属性,包含两个方法GetCustomAttributes(Boolean)和获取指定的自定义属性GetCustomAttributers(Type,Boolean) 获取指定类型的自定义属性。

Module myModule = moduleArray[0];
object[] attributes;
attributes = myModule.GetCustomAttributes(true);

3.9 GetField方法

包含两个方法GetField(String)返回具有指定名称的方法和GetField(String,BindingFlags)返回具有指定名称和绑定特性的字段。返回字段的类型为FieldInfo。

3.10 GetFields()方法

返回在模块上定义的全局字段。包含两个方法GetFields(BindingFlags)返回在于指定绑定标志匹配的模块上定义的全局字段和GetFields()返回在模块上定义的全局字段。此方法返回一个类型为FieldInfo的数组。表示在与指定的绑定标志匹配的模块上定义的全局字段;如果没有全局字段匹配绑定标志,则返回空数组。

3.11 GetMethods()方法

此方法返回模块定义的全局方法。包含两个重载方法:

GetMethods():返回在模块中定义的全局方法。

GetMethods(BindingFlags):返回在与指定的绑定标志匹配的模块上定义的全局方法。

此方法返回模块中定义的所有全局方法的MethodInfo对象数组;如果没有全局方法,则返回空数组。

3.12 GetMethod()方法

此方法返回具有指定条件的方法。此方法包含以下三个重载:

  • GetMethod(String):返回具有指定名称的方法。
  • GetMethod(String,Type[]):返回具有指定名称和参数类型的方法。
  • GetMethod(String,BindingFlags,Binder,CallingConvertions,Type[],ParameterModifier[]):返回具有指定名称,绑定信息,调用约定和参数类型及修饰符的方法。

3.13 GetType()方法

此方法返回指定的类型。此方法包含三个重载方法:

  • GetType(String):返回指定的类型,执行区分大小写的搜索。
  • GetType(String,Boolean):返回指定的类型,通过指定的区分大小写搜索模块。
  • GetType(String,Boolean,Boolean):返回指定的类型,指定是否对该模块进行区分大小写的搜索;如果找不到该类型,则指定是否引发异常。

3.14 GetCustomAttribute方法

此方法是Module类的扩展属性,检索应用于指定元素的自定义属性。有以下重载方法:

  • GetCustomAttribute(Assembly,Type) :检索应用于指定程序集的指定类型的自定义特性。
  • GetCustomAttribute(MemberInfo,Type) :检索应用于指定成员的指定类型的自定义特性。
  • GetCustomAttribute(Module,Type) :检索应用于指定模块的指定类型的自定义特性。
  • GetCustomAttribute(ParameterInfo,Type) :检索应用于指定参数的指定类型的自定义特性。
  • GetCustomAttribute(MemberInfo,Type,Boolean) :检索应用于指定成员的指定类型的自定义特性,并可选择检查该成员的上级

四、总结

本文讲解反射中常用的使用类AssemblyModule类,及如何将程序集通过反射获取对应的信息,下一篇将注重讲解Type、MethodInfo、FieldInfo及CustomAttributes等。

五、参考

https://learn.microsoft.com/zh-cn/dotnet/api/system.reflection.assembly?view=net-7.0

https://learn.microsoft.com/zh-cn/dotnet/api/system.reflection.module?view=net-7.0

12-20 14:20