如鹏网.Net高级技术8.反射

时间:2021-05-12 21:57:13

反射在C#是比较常用的一个技术点,vs中的智能提示,我们使用的反编译工具都可以通过反射实现,

首先要了解程序集。在C#中的.dll文件和项目生成的.exe文件都是程序集。

反射就是动态获取程序集中的元数据来操作类型的。

Type类是在反射中经常用到的。

在该段课程中还会介绍几个反射中常用的方法,最后的时候通过反射做一个插件的案例

此章节的所有代码在反射.rar这个文件中。

-----------------------------------------------------------------------------------------------------

什么是程序集? 程序集(Assembly),可以看做是一堆相关类打一个包。

程序集是.net中的概念

。 .net中的dll与exe文件都是程序集。(exe与dll的区别?)

程序集包含:类型元数据(描述在代码中定义的每一类型和成员,二进制形式)、程序集元数据(程序集清单、版本号、名称等)、IL代码(这些都被装在exe或dll中)、资源文件。

每个程序集都有自己的名称、版本等信息。这些信息可以通过AssemblyInfo.cs文件来自己定义。

使用程序集的好处? 程序中只引用必须的程序集,减小程序的尺寸。

程序集可以封装一些代码,只提供必要的访问接口。

如何添加程序集的引用? 添加路径、项目引用

不能循环添加引用

在c#中添加其他语言编写的dll文件的引用

---------------------------------------------------------------------------------------

反射

反射无处不在,我们天天在使用。Vs的智能提示,就是通过反射获取到类的属性、方法等。还有反编译工具也是通过反射实现

反射:就是动态获取程序集中的元数据来操作类型的。

Type类实现反射的一个重要的类,通过它我们可以获取类中的所有信息包括方法、属性等。可以动态调用类的属性、方法。 Type是对类的描述。如何获取Person类中的所有属性?

反射就是直接通过.dll来创建对象,调用成员。

通过类型元数据来获取对象的一些相关信息,并且还可以实例化对象调用方法等,这个就叫做“反射”。

反射让创建对象的方式发生了改变。

编译器的智能提示就是反射的一个应用。

---------------------------------------------------------------------------------------

Type类

Type类的使用

通过类获得Type:Type t = typeof(Person)

通过对象获得类的Type:Type t = p.GetType()

调用Assembly的GetExportedTypes方法可以得到Assembly中定义的所有的public类型。

调用Assembly的GetTypes()方法可以得到Assembly中定义的所有的类型。

调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息。

插件:扩展主程序功能的dll.

---------------------------------------------------------------------------------------

动态创建对象

Activator.CreateInstance(Type t)会动态调用类的无参构造函数创建一个对象,返回值就是创建的对象,如果类没有无参构造函数就会报错。

GetConstructor(参数列表);//这个是找到带参数的构造函数。

Type类的方法:在编写调用插件的程序时,需要做一系列验证。

bool IsAssignableFrom(Type c):(直译:是否可以从c赋值)判断当前的类型的变量是不是可以接受c类型变量的赋值。 typeof(IPlugin).IsAssignableFrom(t)

bool IsInstanceOfType(object o):判断对象o是否是当前类的实例(当前类可以是o的类、父类、接口)

bool IsSubclassOf(Type c):判断当前类是否是类c的子类。

类的事,没有接口的事。

IsAbstract,判断是否为抽象的,含接口

---------------------------------------------------------------------------------------

动态调用成员

MemberInfo类 抽象类,有很多子类,下面讲的类都继承自它,获取程序集成员的相关信息(类型、方法、事件、字段和属性) PropertyInfo 获取属性

主要成员:CanRead、CanWrite、PropertyType属性类型;

  SetValue、GetValue:读取值,设置值,第一个参数是实例对象,因为set、get要针对具体实例,最后一个参数null。

  pInfo.SetValue(p1, 30, null)

 

MethodInfo 获取方法

   MethodInfo都是和具体对象不相关的,所以需要第一个参数指定要执行的对象。

FieldInfo 获取字段

EventInfo 获取事件

----------------------------------------------------------------------------------------------------

 开发插件步骤

创建接口项目,通过接口定义插件怎么去实现

创建插件项目,创建两个插件一个实现汉英翻译功能,一个实现定时关机功能。插件项目要引用接口项目。编译时让插件项目生成在主程序的debug/plugin目录下

创建主程序,主程序要添加对接口项目的引用(不需要对插件引用,对插件的调用是动态的)

主程序中读取Plugin目录下的所有dll文件,加载成Assembly Ass.GetExportedTypes读取Assembly中的公共类型

IsAssignableFrom判断对象能否委派给某类型,是否是类并且不能使抽象类

动态添加菜单

如鹏网:http://www.rupeng.com