c#进阶教程(一)理解反射

c#进阶教程(一)理解反射c#的运行机制是由c#编译器将程序集打包成中间语言(MSIL),再由即时编译器(JIT)将中间语言编译成本地机器码来执行;一个应用程序一般由多个

大家好,欢迎来到IT知识分享网。

c#的运行机制是由c#编译器将程序集打包成中间语言(MSIL),再由即时编译器(JIT)将中间语言编译成本地机器码来执行;一个应用程序一般由多个程序集(Assembly)组成,程序集是类、接口、结构体等类型的承载体,而反射是能够在运行时构建程序集、类、接口等类型实例的一种技术。

一、动态载入程序集

使用Assembly.Load 方法加载程序集最简单直接

c#进阶教程(一)理解反射

Load方法会到应用程序集的根目录、私有子目录等位置查找程序集,如果没有找到会抛出异常。

Assembly.LoadFrom允许根据一个程序集名称或程序(网络)路径来加载

c#进阶教程(一)理解反射

Assembly.LoadFile允许从任意位置(本地或网络地址)加载程序集,且不加载依赖,依赖文件需要AppDomain的AssemblyResolve事件来注册一个回调方法

c#进阶教程(一)理解反射

如果只是想知道程序集中的元数据信息而不执行里面的任何代码应该使用Assembly.ReflectionOnlyLoad和Assembly.ReflectionOnlyLoadFrom

二、动态构建对象的实例

先加载实例所在的程序集,通过程序集来获取实例的类型,再利用Activator的CreateInstance方法来构造具体实例

c#进阶教程(一)理解反射

CreateInstance 方法有多个重载方法,主要是使用有参和无参构造函数。

需要注意的是,如果使用程序名称加实例全称来构造实例,返回的是一个句柄,它只能转换为最终类,不能被转换为基类或接口

c#进阶教程(一)理解反射

三、动态设置字段的值

c#进阶教程(一)理解反射

四、动态设置属性的值

想要获取一个对象的属性,需要使用Type.GetProperty(“Name”) 方法得到一个属性对象,通过属性对象的GetValue与SetValue来操作属性

c#进阶教程(一)理解反射

五、动态调用方法

使用类型实例的Type.GetMethod(“methodname”)来获取某个方法的对象,通过方法的Invoke方法来执行具体方法,可以传递相关参数

c#进阶教程(一)理解反射

六、动态构造实例

c#进阶教程(一)理解反射

七、构造事件处理

c#进阶教程(一)理解反射

八、使用案例分析

假设需要设计一个通用的数据库访问接口,该接口既要支持SqlServer数据库也要支持MySql数据库,我们会定义这样一个接口:

c#进阶教程(一)理解反射

SqlServer的实现如下:

c#进阶教程(一)理解反射

MySql数据库的实现如下:

c#进阶教程(一)理解反射

在使用时我们常见的做法是,根据参数来实例化不同的类:

c#进阶教程(一)理解反射

这种方式虽然也实现了动态构建,但如果后续要支持更多的数据库,就不得不修改构建方法,增加分支。这种做法也违背了开闭原则。

使用反射来改进:

c#进阶教程(一)理解反射

不管后续我们增加多少种数据库类型,都不用修改实例的创建代码,这就是反射的魅力。

使用反射技术还可以实现一种外挂功能,宿主程序定义一个接口,由其他程序集或者其他公司提供的程序集来实现这个接口,这样可以构建出可扩展的应用程序。

九、反射的性能

反射是利用字符串实例名称到程序集的元数据中进行扫描,且不区分大小写,这样的效率极低且类型不安全。

反射的速度比较慢,在使用反射时其类型和成员名称在编译时未知,在运行时通过名称来查找匹配。

十、如何提高反射的性能

让反射构建实例的基类或接口在编译时已知,反射构建实例后转换为已知基类或接口。

原创不易,希望各位粉丝朋友们伸出你的金手指点赞加关注,你的支持将是我持续创作的动力。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/57210.html

(0)
上一篇 2024-05-03 06:50
下一篇 2024-05-09 21:33

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信