详解C# 反射(Reflection)

C# 反射(Reflection)

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。

您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

优缺点

优点:

1、反射提高了程序的灵活性和扩展性。
2、降低耦合性,提高自适应能力。
3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

反射(Reflection)的用途

反射(Reflection)有下列用途:

  • 它允许在运行时查看特性(attribute)信息。
  • 它允许审查集合中的各种类型,以及实例化这些类型。
  • 它允许延迟绑定的方法和属性(property)。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。

查看元数据

我们已经在上面的章节中提到过,使用反射(Reflection)可以查看特性(attribute)信息。

System.Reflection 类的 MemberInfo 对象需要被初始化,用于发现与类相关的特性(attribute)。为了做到这点,您可以定义目标类的一个对象,如下:

System.Reflection.MemberInfo info = typeof(MyClass);

下面的程序演示了这点:

using System;

[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
  public readonly string Url;

  public string Topic // Topic 是一个命名(named)参数
  {
   get
   {
     return topic;
   }
   set
   {

     topic = value;
   }
  }

  public HelpAttribute(string url) // url 是一个定位(positional)参数
  {
   this.Url = url;
  }

  private string topic;
}
[HelpAttribute("Information on the class MyClass")]
class MyClass
{
}

namespace AttributeAppl
{
  class Program
  {
   static void Main(string[] args)
   {
     System.Reflection.MemberInfo info = typeof(MyClass);
     object[] attributes = info.GetCustomAttributes(true);
     for (int i = 0; i < attributes.Length; i++)
     {
      System.Console.WriteLine(attributes[i]);
     }
     Console.ReadKey();

   }
  }
}

当上面的代码被编译和执行时,它会显示附加到类 MyClass 上的自定义特性:

HelpAttribute

实例

在本实例中,我们将使用在上一章中创建的 DeBugInfo 特性,并使用反射(Reflection)来读取 Rectangle 类中的元数据。

using System;
using System.Reflection;
namespace BugFixApplication
{
  // 一个自定义特性 BugFix 被赋给类及其成员
  [AttributeUsage(AttributeTargets.Class |
  AttributeTargets.Constructor |
  AttributeTargets.Field |
  AttributeTargets.Method |
  AttributeTargets.Property,
  AllowMultiple = true)]

  public class DeBugInfo : System.Attribute
  {
   private int bugNo;
   private string developer;
   private string lastReview;
   public string message;

   public DeBugInfo(int bg, string dev, string d)
   {
     this.bugNo = bg;
     this.developer = dev;
     this.lastReview = d;
   }

   public int BugNo
   {
     get
     {
      return bugNo;
     }
   }
   public string Developer
   {
     get
     {
      return developer;
     }
   }
   public string LastReview
   {
     get
     {
      return lastReview;
     }
   }
   public string Message
   {
     get
     {
      return message;
     }
     set
     {
      message = value;
     }
   }
  }
  [DeBugInfo(45, "Zara Ali", "12/8/2012",
    Message = "Return type mismatch")]
  [DeBugInfo(49, "Nuha Ali", "10/10/2012",
    Message = "Unused variable")]
  class Rectangle
  {
   // 成员变量
   protected double length;
   protected double width;
   public Rectangle(double l, double w)
   {
     length = l;
     width = w;
   }
   [DeBugInfo(55, "Zara Ali", "19/10/2012",
      Message = "Return type mismatch")]
   public double GetArea()
   {
     return length * width;
   }
   [DeBugInfo(56, "Zara Ali", "19/10/2012")]
   public void Display()
   {
     Console.WriteLine("Length: {0}", length);
     Console.WriteLine("Width: {0}", width);
     Console.WriteLine("Area: {0}", GetArea());
   }
  }//end class Rectangle 

  class ExecuteRectangle
  {
   static void Main(string[] args)
   {
     Rectangle r = new Rectangle(4.5, 7.5);
     r.Display();
     Type type = typeof(Rectangle);
     // 遍历 Rectangle 类的特性
     foreach (Object attributes in type.GetCustomAttributes(false))
     {
      DeBugInfo dbi = (DeBugInfo)attributes;
      if (null != dbi)
      {
        Console.WriteLine("Bug no: {0}", dbi.BugNo);
        Console.WriteLine("Developer: {0}", dbi.Developer);
        Console.WriteLine("Last Reviewed: {0}",
                    dbi.LastReview);
        Console.WriteLine("Remarks: {0}", dbi.Message);
      }
     }

     // 遍历方法特性
     foreach (MethodInfo m in type.GetMethods())
     {
      foreach (Attribute a in m.GetCustomAttributes(true))
      {
        DeBugInfo dbi = (DeBugInfo)a;
        if (null != dbi)
        {
         Console.WriteLine("Bug no: {0}, for Method: {1}",
                        dbi.BugNo, m.Name);
         Console.WriteLine("Developer: {0}", dbi.Developer);
         Console.WriteLine("Last Reviewed: {0}",
                        dbi.LastReview);
         Console.WriteLine("Remarks: {0}", dbi.Message);
        }
      }
     }
     Console.ReadLine();
   }
  }
}

当上面的代码被编译和执行时,它会产生下列结果:

Length: 4.5
Width: 7.5
Area: 33.75
Bug No: 49
Developer: Nuha Ali
Last Reviewed: 10/10/2012
Remarks: Unused variable
Bug No: 45
Developer: Zara Ali
Last Reviewed: 12/8/2012
Remarks: Return type mismatch
Bug No: 55, for Method: GetArea
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks: Return type mismatch
Bug No: 56, for Method: Display
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks:

以上就是详解C# 反射(Reflection)的详细内容,更多关于C# 反射(Reflection)的资料请关注我们其它相关文章!

(0)

相关推荐

  • C# 反射(Reflection)的用处分析

    乱侃 作为一名新手,一直没有勇气去写一篇分享.原因有很多:诸如:自己水平有限.语言表达不准确.写出的东西没有一点技术点被人嘲笑.今天在公司听了内部员工的一个分享,其中最重要的一点是:提升自身水平的最佳的途径就是--交流.不管你是通过什么途径,交流也好.整理成文字分享也好等等都是很好的方式.故此,今天献丑写一篇自己的心得分享,欢迎各路大神的指教!    需求背景 今天接到的需求里面有个这样的需求,如下图所示,需要打印出如Excel内容呈现的单据.     动手操作第一版本 而为了实现这个业务需要涉

  • C#反射(Reflection)对类的属性get或set值实现思路

    近段时间,有朋友叫Insus了解一下反射(Reflection)方面的知识,反射提供了封装程序集.模块和类型的对象(Type类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. 下面的例子,是Insus练习对一个类别的属性进行set和get值. 首先写一个类,再写一个可读写的属性: 复制代码 代码如下: using System; using System.Collections.Ge

  • C#基于Linq和反射实现数据持久化框架Xml4DB详解

    我们知道目前大部分的数据库都是关系型数据库, 所谓关系型数据库,就是指建立在关系模型 基础之上的数据库系统,如Oracle.SQL Server.Access.MySQL等.关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织.一个偶然的机会我接触到了DB4O,它是一个完全面向对象的开源数据库,它的出现完全颠覆了传统的数据库在人们心中的形象,因为传统的数据库需要在数据体.实体之间转换,而且需要映射文件提供映射关系.正是这个项目让我产生了编写Xml4DB的想

  • 关于C#反射 你需要知道的

    通常,反射用于动态获取对象的类型.属性和方法等信息.今天带你玩转反射,来汇总一下反射的各种常见操作,捡漏看看有没有你不知道的. 获取类型的成员 Type 类的 GetMembers 方法用来获取该类型的所有成员,包括方法和属性,可通过 BindingFlags 标志来筛选这些成员. using System; using System.Reflection; using System.Linq; public class Program { public static voidMain() {

  • 详解C# 反射(Reflection)

    C# 反射(Reflection) 反射指程序可以访问.检测和修改它本身状态或行为的一种能力. 程序集包含模块,而模块包含类型,类型又包含成员.反射则提供了封装程序集.模块和类型的对象. 您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型.然后,可以调用类型的方法或访问其字段和属性. 优缺点 优点: 1.反射提高了程序的灵活性和扩展性. 2.降低耦合性,提高自适应能力. 3.它允许程序创建和控制任何类的对象,无需提前硬编码目标类. 缺点: 1.性能问题:使用反射基本

  • 详解JAVA 反射机制

    什么是反射? 反射机制是在程序运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制. 反射的作用 1.可以实现简单的反编译,获取类中的属性和方法等基本信息,.class->java 2.通过反射机制获取类的属性.方法等 在使用eclipse时,通过对象引用.的方式,eclipse就会将这个对象中的所有属性和方法展示出来,这个就是利用的反射机制.其实反射应用最多的

  • 详解Java 反射和反射的应用场景

    反射机制介绍 JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制. 获取 Class 对象的两种方式 如果我们动态获取到这些信息,我们需要依靠 Class 对象.Class 类对象将一个类的方法.变量等信息告诉运行的程序.Java 提供了两种方式获取 Class 对象: 1.知道具体类的情况下可以使用: Class alunbarCla

  • Java 类型信息详解和反射机制介绍

    RTTI RTTI(RunTime Type Information)运行时类型信息,能够在程序运行时发现和使用类型信息,把我们从只能在编译期知晓类型信息并操作的局限中解脱出来 传统的多态机制正是 RTTI 的基本使用:假设有一个基类 Shape 和它的三个子类 Circle.Square.Triangle,现在要把 Circle.Square.Triangle 对象放入 List<Shape> 中,在运行时,先把放入其中的所有对象都当作 Object 对象来处理,再自动将类型转换为 Shap

  • 详解Java反射创建对象

    一.什么是反射 Java Reflaction in Action中的解释:反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变.通俗的讲就是反射可以在运行时根据指定的类名获得类的信息 个人理解:就是我们对于创建对象我们除了通过 new关键字创建外,还能通过什么创建呢?private的属属性真的不能获取吗?反射就能做到打破这些所谓的规则反射和new创建对象谁的效率高? new 二.通过类对象调用newInstance()方法,适用于无参构造方法 2.1 类名.class p

  • 图文详解java反射机制及常用应用场景

    目录 一.什么是java反射? 二.HelloWorld 三.类加载与反射关系 四.操作反射的java类 4.1.获取Class对象的三种方法 4.2.获取Class类对象的基本信息 4.3.获得Class对象的成员变量 4.4.获取Class对象的方法 4.5.方法的调用 4.6.创建类的对象(实例化对象) 五.反射的常用场景 5.1.通过配置信息调用类的方法 5.2.结合注解实现特殊功能 5.3.按需加载jar包或class 六.反射的优缺点 一.什么是java反射? 在java的面向对象编

  • 详解Java反射实现Aop代理

    利用反射生成JDK的动态代理,也就是AOP中的AOP代理,代替目标对象,从而在代码中织入增强. 定义代理接口 由于JDKf动态代理只能为接口创建动态代理,故先定义接口,假定我们需要对数据的Save方法添加事务处理,我们有一个UserDao接口,里面有一个Save方法,代码如下: public interface UserDao { public void save(); } 定义代理实现 下面具体来实现接口定义的Save方法,我们采用下面的代码来实现. public class UserDaoI

  • 详解Java反射各种应用

    Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Class对象 构造器 变量 方法 私有变量与私有方法 注解 泛型 数组 本文也将从上面几个方面来介绍Java反射.本文涉及的所有代码均在反射代码 首先放出一个Java类作为反射的研究对象,类的内容如下: public abstract class FatherObject implements Runnable{ public v

  • Java 用反射设置对象的属性值实例详解

    Java 用反射设置对象的属性值实例详解 /** * 用反射设置对象的属性值 * @param obj 需要設置值的對象 * @param fieldName 需要設置值的屬性 * @param value 需要设置的值 * @return 设置值后的对象 */ private Object invoke(Object obj, String fieldName, Object value) { String firstWord = fieldName.substring(0, 1).toUpp

  • 详解Java如何实现自定义注解

    目录 概念 作用 JDK中预定义的一些注解 注解生成文档案例 自定义注解 格式 本质 属性:接口中的抽象方法 元注解:用于描述注解的注解 在程序使用(解析)注解:获取注解中定义的属性值 案例:通过自定义注解定义一个简单的测试框架 总结 概念 概念:说明程序的.给计算机看的 注释:用文字描述程序的.给程序员看的 定义:注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法

随机推荐