• 【C#】:浅谈反射机制 【转】


    http://blog.csdn.net/lianjiangwei/article/details/47207875 

    什么是反射?

            反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。

            反射机制是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息。

            

            通俗的来讲,就是反射是通过一个对象去了解另一个对象的内部结构和信息,即使在你不知道那个对象存在的情况下。就好比是海船的声纳探测一样,我们并不知道海水深处是什么情况,但是通过声呐反射回来的情况,就可以掌握障碍物的大小,移动速度等等,和我们所谈论的反射是一个道理。但是我们在程序使用反射不仅可以获取,类的内部情况,还可以操作调用反射类的方法,简直是太神奇了。

            为什么用反射?

            1使用了反射后,你的程序在更新的时候无需重新编译,只要将更新的Dll换掉即可完成程序的更新和升级。

            2将反射和配置文件相结合,可以开发出功能随意增删改的软件,具备了极大地灵活性和扩展性。

            3反射提高了程序的灵活性,降低了耦合性,提高了自适应能力,同时也大大提高了程序的复用性。

            但是要强调的一点是,任何事物都有两面性,不是所有场合都适合使用反射技术的。使用反射也会有其缺点:

            1首先带来的一个很大的问题就是——性能问题,使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。

            2使用反射会使程序内部逻辑模糊化,程序员在调试代码的时候西瓦昂看到清晰的程序逻辑,而反射却绕过了源代码,因此会带来一定的维护性问题,同时反射代码比相应的直接代码更加复杂。

            综上所述:反射机制有其适用的场合,只要用来开发对灵活性和扩展性要求很高的软件系统,普通的程序没必要使用。

            怎么用反射?

            首先声明我对反射的使用不是很深入,只是做了一些简单的尝试,下面用一个小Demo来说明如何在C#中使用反射获取一个类的属性、方法以及修改属性和调用方法等。代码如下:

            首先我们先写一个目标类Student     

    [csharp] view plain copy
    1. <span style="font-size:18px;">using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace ITOO.Reflection.Student  
    7. {  
    8.     public class Student  
    9.     {  
    10.         public string Name { get; set; }  
    11.   
    12.         public int Age { get; set; }  
    13.   
    14.         // 默认构造函数  
    15.         public Student()  
    16.         {  
    17.             this.Age = 24;  
    18.             this.Name = "连江伟";  
    19.         }  
    20.         //带参数的构造函数  
    21.         public Student(string name,int age)  
    22.         {  
    23.             this.Name = name;  
    24.             this.Age = age;  
    25.         }  
    26.   
    27.         public void Hello()  
    28.         {  
    29.             Console.WriteLine("我是"+Name +",我今年"+Age +"岁了!");  
    30.         }  
    31.     }  
    32. }</span>  

            然后我们在控制台应用程序中去利用反射操纵这个类 

    [csharp] view plain copy
    1. <span style="font-size:18px;">using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Reflection;  
    6.   
    7. namespace ITOO.Reflection.Client  
    8. {  
    9.     class Program  
    10.     {  
    11.         static void Main(string[] args)  
    12.         {  
    13.             //动态加载DLL,这个LoadFile最方便,参数就是dll的路径。  
    14.             var asm = Assembly.LoadFile(@"C:UsersljwDesktop学习例子ITOO.Reflection.TestITOO.Reflection.StudentinDebugITOO.Reflection.Student.dll");  
    15.             //获取Student类的类型  
    16.             var type = asm.GetType("ITOO.Reflection.Student.Student");  
    17.             //创建该类的实例  
    18.             var instance = asm.CreateInstance("ITOO.Reflection.Student.Student");  
    19.             //为学生类的属性赋值  
    20.             type.GetProperty("Name").SetValue(instance, "段天涯", null);  
    21.             type.GetProperty("Age").SetValue(instance, 18, null);  
    22.             //获取Student类的方法  
    23.             var method = type.GetMethod("Hello");  
    24.             //调用Student类的成员方法Hello  
    25.             method.Invoke(instance, null);  
    26.             Console.Read();  
    27.         }  
    28.     }  
    29. }</span>  

            小结一下:对于反射这个概念,一开始我是比较模糊的,虽然很多次的听到别人在说在讲,但是由于没有自己去查资料去研究,去动手代码实现,终究不能感同身受,理解其中的原理和思想,如今阅读了大量的博客和文章之后,又动手实践了一下,有了一些浅浅的理解,由于Donet的反射机制是封装好的,所以对于反射内部实现原理还不清楚,期待以后能够继续深入学习。

  • 相关阅读:
    hdu 1084(水题)
    hdu 1872(稳定排序)
    NOI 2008 志愿者招募 / bzoj 1061 (最小费用最大流)
    hdu 1019(LCM)
    hdu 1876(dp)
    Codeforces Round #171 (Div. 2)
    poj 3422(最小费用最大流)
    poj 3264(简单线段树)
    Codeforces Round #156 (Div. 2)
    Codeforces Round #169 (Div. 2)
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/7338401.html
Copyright © 2020-2023  润新知