`
starnc
  • 浏览: 144759 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

论反射

    博客分类:
  • .NET
阅读更多

1   反射

反射是很多类库在实现一些很炫的功能的时候会常用的技术(比如ORM等)。我们需要动态的使用类型的时候就需要很灵活的运用反射的技术。

2   反射的原理

反射是一种可以获取类型的结构,包括所有成员,动态创建对象并可以动态的操作对象的技术。我们通过CLR的支持可以在运行时完成一些动态的操作。反射在很多时候配合多态,可以替代switch等结构。

.NETCLR在编译的时候会把类型的结构等信息生成元数据和代码一起编译在程序集里,然后通过.NET所提供的System.Refrection命名空间下的各种类去操作。

3  反射的基本操作

反射的操作方式很多,我们主要介绍几种反射简单的使用方法,这些操作都是在实际项目开发过程当中比较常用的。

在进行反射操作的时候,首先需要得到要操作类型的信息,这些信息通过System.Type类型来封装。获取一个类的Type 对象有下面的3种方法:

3.1     通过对象的GetType()方法

每个对象都会继承由Object,,而且都重写了Object所提供的GetType()方法,这些方法能够正确的返回对象真实类型的System.Type对象。

3.2     通过typeof()操作符

如果没有对象怎么获取一个类型的Type呢?我们可以通过typeof(类型)的方式来获取。

4        通过Type类的GetType()方法

还有一种方式是通过Type的静态方法GetType来获取,这里需要类型的完全限定名,即从类型所属的根命名空间开始的完全名称,比如Type类就是System.Type

这三种方式前两种比较方便所以用的比较多,我们在不同的情况下需要选择正确的方式去获取。比如如果通过字符串参数传递一个类的名称,或者通过配置文件设定的类的名称使用Type.GetType()方法。如果是已经传递进来一个对象,那么不管参数是什么类型,比如参数是Object类型的,这表明任何引用类型的对象都可以传递进来,这个时候使用第一种方式,直接执行对象的GetType()方法,就可以返回正确的类型。而TypeGetType方法限制比较大,因为这个方法只能在程序集中搜索类型,所以对于多程序集的程序来说使用上有点麻烦。

得到类型的信息后就可以通过Type类型深入进去开始获取类型内部的信息。Type有很多GetXXX的方法,我们看名字都能很直接的看出来是获取什么的。这里我们可以获取类内部的很多结构,包括属性、方法、字段等等。这些结构都用定义在System.Refrection下的各种对应的包装类给定义出来,我们可以通过相关的包装类获取这些结构的信息。也可以直接操作这些结构,比如给属性赋值,获取属性的值等等。

我们通过PropertyInfo类来做例子,其它的同理可得。如果详细说明可以另写一本书了,所以这里点到为止,起码能让你初窥门径了。

假设我们有如下一个类:

class A

{

   private int _Data;

   public int Data

   {

       get { return _Data; }

       set { _Data = value; }

   }

   private string _Str;

   public string Str

   {

       get { return _Str; }

       set { _Str = value; }

   }

}

我们可以通过以下代码来得到一个A类型的对象的所有属性的名称:

Type a = typeof(A);

PropertyInfo[] PropertysInA = a.GetProperties();

foreach (PropertyInfo Property in PropertysInA)

{

   Console.WriteLine(Property.Name);

}

这里PropertyInfo类型的对象就是包含属性信息的类型了,我们在这里可以通过Property变量来操作属性。我们假设有个A类型的对象,我们通过反射的方式来给他的属性赋值:

void SetObjectValue(object AObject, string PropertyName, string Value)

{

   Type TypeOfA = AObject.GetType();

   PropertyInfo Property = TypeOfA.GetProperty(PropertyName);

   Property.SetValue(AObject, Value, null);

}

同理,,我们也可以用GetValue方法从属性获取值。SetValue()的第三个参数为null,是因为要反射的属性也包括索引类的属性,所以第三个个参数是用来来传递参数的值。一般的属性就为null就行了。

如果我们只知道一个类型的名字,如何创建它的对象呢?这里我们需要通过System下的一个类型来实现。这个类叫Activator,它是专门用来实例化对象的。我们可以通过他的静态方法CreateInstance(),参数可用Type类型的对象比如创建A类型的对象:

A a = (A)Activator. CreateInstance(typeof(A));

这里返回的是Object类型的对象,如果要赋值需要强制转换,当然这里也可以用as操作来转换:

A a= Activator. CreateInstance(typeof(A)) as A;

还有一个泛型的方法可以通过传递类型参数来避免强制转换,关于泛型我们在后面泛型的部分会详细介绍,这里只看这个方法的例子:

A a = Activator. CreateInstance<A>();

反射是很强大的,我们可以通过它很灵活的去操作对象。但是反射也是很邪恶的,带来灵活的代价就是效率。经过测试我们发现,直接操作对象和通过反射操作对象的效率相差200倍,所以接下来我们就来谈谈如何正确使用反射。

5 正确使用反射

反射产生的性能问题是一个很大的难题,所以我们应该尽量避免滥用反射。但是有的时候避免不了的话也只有去面对了,比如很多模板引擎和ORM都是没有办法避免频繁使用反射的。

因为反射得来的对象都是很昂贵的,所以我们要尽量重复利用,比如使用缓存将对象缓存起来。如果不需要对象尽量不要用反射创建对象。我们这里限于篇幅不能铺开叙述,所以只介绍一种通过接口来提供反射性能的方法。

比如有一系列的对象都是用来操作数据库的,有的专门用来操作SQL Server,有的用来操作Access。我们获取配置里的字符串通过反射去获取相应的实例来操作数据库。这里最笨的方法就是通过Activator获取对象后,通过MethodInfo去调用相应的方法,这里得到对象就是个很昂贵的操作了,每次调用都用反射,效率太低了。为了提高效率,我们通过接口来将这些对象的相同操作封装起来:

interface IDAL

{

   void Select();

   void Update();

   void Delete();

   void Insert();

}

那么每一次通过Activator得到对象后都赋值给IDAL定义的对象:

IDAL Accessor = Activator. CreateInstance(Type.GetType("SQLServer")) as IDAL;

这样子以后调用方法都不需要通过反射了,直接通过Accessor.XXXX就能操作了。这样子的效率就比每一次都用反射去调用方法要快得多。

这个Accessor对象是通过Activator得到的所以很“昂贵”。我们最好尽量把这个对象缓存起来,下一次直接通过缓存使用,这样子可以大大的提高效率。

 

以上这篇文章不错,值得看

分享到:
评论

相关推荐

    智能反射面(IRS)在无线通信安全领域应用的论文复现-随N变化部分

    智能反射面(IRS)在无线通信安全领域的应用已经成为现代通信技术的一个重要研究方向。这篇论文复现了关于IRS如何增强无线通信安全性的研究成果,特别是针对N值变化的影响。在这个领域,IRS,或称为Reconfigurable ...

    C++实现的反射+论文原理讲解

    在编程领域,反射是一种强大的特性,它允许程序在运行时检查和操作自身的结构和行为。在C++中,反射的概念相对较新,与Java或.NET框架中的反射机制不同,C++并没有内置的反射系统。然而,开发者们通过各种手段来模拟...

    2021年国赛A题(FAST主动反射面形状调节)论文+代码材料.zip

    【标题】:“2021年国赛A题(FAST主动反射面形状调节)论文+代码材料.zip”涉及的核心知识点主要包括数学建模、天文学、物理学以及计算机编程。FAST(Five-hundred-meter Aperture Spherical Telescope,即500米口径...

    遥感反射率相关论文(定义、图像处理)

    遥感反射率是遥感技术中的一个重要概念,它在地球观测和环境研究中扮演着核心角色。遥感是指从远距离获取地表信息的技术,通过卫星或飞机等平台上的传感器来探测地面物体对电磁辐射的反射、吸收和发射。反射率则是...

    研究论文-基于反射内存网的导航系统通讯技术.pdf

    针对导航系统通讯对于实时性、可靠性、高速性的要求,提出了将反射内存网应用于导航通讯中.介绍了反射内存网的特点,阐述了反射内存网的工作原理与通信机制,并与传统计算机网络技术进行了比较.重点给出了反射内存网...

    多层膜反射率的计算 (2011年)

    在光学领域中,多层膜反射率的计算是一个重要的研究课题,其计算结果对于光学薄膜的设计与应用有着至关重要的影响。本文介绍的是如何基于菲涅尔公式,采用递推法推导出多层膜的反射率计算公式,并通过Visual Basic...

    论文研究-含超导材料的一维三元光子晶体的宽带全向反射器设计 .pdf

    1. 宽带全向反射器是指在宽频范围内具有全向反射特性的反射器。 2. 文中设计了一种含超导材料的一维三元光子晶体宽带全向反射器。 3. 研究发现,通过改变超导材料层的厚度和调整温度,可以实现对全向带隙的调节。 4....

    论文研究 - 沥青和斜纹岩的宏观识别在页岩和反射率检测中的应用研究

    其热演化必须通过页岩沥青反射率和笔石反射率来测试。 DM4500显微镜用于测试Graptolite反射率和沥青反射率的页岩。 结果表明,页岩斜面上的反射率在2.91%-3.20%之间,平均3.08%; 沥青碎片反射率在2.93%-3.19%...

    一种多层膜反射镜反射率的测量方法

    多层膜反射镜是一种在X射线波段具有高反射率的光学元件,它通过沉积多层不同材料的薄膜来实现对特定波长X射线的高反射。多层膜反射镜的反射率测量是该领域研究的关键技术之一,通过精确测量反射率,可以评估多层膜的...

    光学_关于光的反射、折射、拐折和颜色的论文

    牛顿的经典物理,光学_关于光的反射、折射、拐折和颜色的论文

    模拟空间辐照环境对SiC反射镜反射率影响研究

    在深入分析给定文件内容的基础上,我们将从模拟空间辐照环境对SiC反射镜反射率影响研究这一主题中提炼出如下知识点: 1. SiC反射镜的应用背景和重要性 SiC(碳化硅)作为一种材料,因其高综合性能被认为是制备新...

    论文研究-天气雷达反射率数据方位分辨率提高.pdf

    天气雷达反射率数据方位分辨率的提高,对中小尺度强对流天气过程的精细探测有重要的意义。以雷达气象积分方程为基础,通过对天气雷达反射率方位数据的过采样,建立雷达测量的低分辨反射率数据与真实气象目标高分辨率...

    论文分享:智能反射面综述、教程

    智能反射面(IRS)是一种无线通信中的新兴技术,它通过大量低成本的被动反射元件来智能调整信号反射,从而动态改变无线信道,以提升通信性能。在未来的无线网络中,IRS-辅助的混合无线网络结合了主动和被动组件,...

    波浪反射系数试验研究

    波浪反射系数是指波浪遇到防波堤等结构物时,波浪能量的反射程度。它是一个无量纲的数值,用来描述波浪在遇到障碍物时波高相对于入射波高的比例,其值介于0到1之间。在港口工程中,防波堤的主要作用是减少风浪对港口...

Global site tag (gtag.js) - Google Analytics