反射的性能

  反射是一个相当强大的机制,它允许我们在运行时构建并使用一个在编译时还不了解的类型及其成员。但它也有两个缺点。

  • 反射会造成编译时无法保证类型的安全性。由于反射使用字符串,所有会丧失编译时的安全性。如果在运行时找不到字符串标明的类型,就会抛出异常。
  • 反射速度慢。由于类型及其成员在编译时未知,需要用字符串来进行标识。System.Reflection空间下的类型在扫描程序集的元数据时,反射要不断的执行字符串搜索。通常字符串的搜索是不执行大小写比较的,这会进一步影响速度。

  使用反射调用一个成员时,也会对性能产生影响。用反射调用一个方法时,首先要将实参打包成一个数组,在内部,反射将这个数组解包到线程栈上。此外,在调用方法前,CLR要检查实参的数据类型。最后,CLR还要保证调用者拥有正确的安全权限来访问调用的成员。

  基于上面的原因,最好避免利用反射来访问字段或者调用方法/属性。如果需要在运行时动态构造实例,可以使用下面的两种技术。

  • 让类型从一个编译时已知的基类派生。在运行时,利用反射构建派生类的实例,将它的引用放到基类的一个变量中(利用转型)。再调用基类中定义的虚方法。
  • 让类型实现一个编译时已知的接口。在运行时,利用反射构建类型的实例,将它的引用放到接口的一个变量中(利用转型)。再调用接口定义的方法。

  关于接口和基类的选择,一般情况应优先选用接口。不过,在需要版本控制的情形中,基类会更加适合,随时向基类中添加成员,派生类会直接继承它,不用重新编译。而接口中添加一个成员后,所有实现该接口的类型都必须修改并重新编译。另外要注意一点,强烈建议基类或是接口类型在自己的程序集中定义,这有助于缓解版本控制问题。(其实,个人理解这样做的原因在于更符合“依赖倒置”原则,使用接口的程序集才是需求方)。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值