现在的位置: 首页 > 综合 > 正文

反射

2014年11月09日 ⁄ 综合 ⁄ 共 3061字 ⁄ 字号 评论关闭

1.什么是反射及用途?

2.哪些情况下会用到反射?

3.反射在实际应用中是怎么用的?

我想弄明白这些问题,可能会对学习反射起到更为积极的作用.

反射是一种机制,这种机制可以让我们获取运行时类型信息.反射运用的比较广泛其中Spring的IOC容器就是通过读取配置文件,利用反射对接口进行实例化.要想清楚的了解反射需要知道,NET应用程序的组成.主要由以下几部分组成:程序集(Assembly),模块(Module),类型(Class).反射可以在程序运行时期得到这几部分的信息.从而达到生成实例进行调用的目的.

那么我们为什么要这样应用呢?这是决定我们是否需要使用反射的问题.试想一下,如果现在有两个不同的团队, A团队服责展现层与逻辑层的工作,而B团队服责持久层的工作.那么在实际情况下,B会提供给A一个DLL库文件供A使用.这样A就可以使用反射这种机制来调用DLL库,即使DLL库的内容改变了,A也不用修改什么.

现在有一个概念需要了解,命名空间与装配件的关系.命名空间就是你使用Using命令时写的一堆字符串,它会告诉程序你使用的类应该从哪里去引入.装配件是程序执行的最小单位,编译出来后是.DLL,.EXE文件这就是装配件.一个命名空间可以出现在多个装配件中,一个装配件可以拥有多个命名空间.如下:

装配件A.DLL

namespace N1

{

   public class AN1{...}

   public class AN2{...}

}

namespace H1

{

  public class AH1{...}

  public class AH2{...} 

}

装配件B.DLL

 

namespace N1

{

   public class BN1{...}

   public class BN2{...}

}

namespace H1

{

  public class BH1{...}

  public class BH2{...} 

}

这里所指的装配件通常是DLL文件.

动态获取类型的方法实际上并没有想像中那么难.

1.Object.GetType()方法,如果你已经获得到一个Object对象,那么你就可以通过GetType方法来取得一个Type的实例从而知道这个对象的一切信息了.

2.另外还有一种方法是使用Type的静态方法GetType(classType),classType是具体的类型名称.需要强调的是这里的classType就是上面所讲的命名空间+类名,比如需要得到String对象类型,那么可以这样写

Type t = Type.GetType("System.String");这里需要注意的是系统默认已经自动引入了这个命名空间所在DLL文件(装配件mscorlib.dll),所以像以上的写并没有什么问题.

Type t = Type.GetType("System.Data.DataTable");这一句在运行的时候就会出现错误,因为命名空间"System.Data.DataTable"所在的DLL文件(System.Data.dll)系统默认是不自动引入的.这时候就需要手动引入DLL文件又或者这样写

Type   t   =   Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0,   Culture=neutral,   PublicKeyToken=b77a5c561934e089");同样你需要将DLL文件放到C#找的到的地方,否则同样会出错.C 反射学习  - jiang_tao_2010 - 小狼.exe

3.上面已经给出两种获取方法,还有第三种方法就是使用Assembly.GetType()方法.

此种方法首先需要获得一下Assembly的实例,Assembly asm=Assembly.Load("命名空间");这同样是在不需要引入DLL文件的时候使用.如果需要引入DLL文件可以这样使用 Assembly asm=Assembly.LoadFile(@"d:/Test.dll");

Type t = asm.GetType("命名空间+类名");

有了Type对象之后就可以自己创建实例,调用方法等.比如可以通过调用GetMethod方法来获取MethodInfo对象

通过Assembly实例的CreateInstance方法来获取对象实例

asm. CreateInstance(t,new object[]{"..."});//类型,对象初始化参数,如果没有可以不写

,在通过MethodInfo对象Invoke方法调用对象的方法时,如果是实例方法那么需要实例对象做参数,如果是静态方法置NULL就可以.

引用一个网上的例子

public void test1()

   {

    System.Reflection.Assembly ass;

    Type type ;

    object obj;

    try

    {

     ass = System.Reflection.Assembly.LoadFile(@"d:/TestReflect.dll");

     type = ass.GetType("Webtest.ReflectTest");//必须使用名称空间+类名称

    System.Reflection.MethodInfo method = type.GetMethod("WriteString");//方法的名称

    obj = ass.CreateInstance("Webtest.ReflectTest");//必须使用名称空间+类名称

    string s = (string)method.Invoke(obj,new string[]{"jianglijun"}); //实例方法的调用

   

    Response.Write(s+"<br>");

    method = type.GetMethod("WriteName");//方法的名称

    s = (string)method.Invoke(null,new string[]{"jianglijun"}); //静态方法的调用

    Response.Write(s+"<br>");

    method = type.GetMethod("WriteNoPara");//无参数的实例方法

    s = (string)method.Invoke(obj,null);

    Response.Write(s+"<br>");

    method = null;

   }

   catch(Exception ex)

   {

    Response.Write(ex+"<br>");

   }

   finally

   {

    ass = null;

    type = null;

    obj = null;

   }

 

  }仅为个人学习,不做发表.

参考文章:http://www.crazycoder.cn/DotNet/Article20596.html

            http://www.cnblogs.com/fineboy/archive/2006/10/10/525348.html

            http://www.cnblogs.com/zhusl118/archive/2008/11/21/1338373.html

            http://www.phpchinaz.cn/c/CSharp/52_5201_1230349985.html

抱歉!评论已关闭.