详解C# 反射(Reflection)

作者:菜鸟教程 时间:2021-09-08 14:42:59 

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:

来源:https://www.runoob.com/csharp/csharp-reflection.html

标签:c#,反射,reflection
0
投稿

猜你喜欢

  • Java实现定时任务的方法详解

    2022-12-30 04:14:00
  • 一篇文章带你入门Java接口

    2023-11-06 02:07:55
  • java如何使用自己的maven本地仓库详解

    2022-08-01 12:13:44
  • Repeater中添加按钮实现点击按钮获取某一行数据的方法

    2022-05-17 08:19:31
  • C#实现状态栏提示信息功能的示例

    2022-01-05 12:36:57
  • Python代码一键转Jar包及Java调用Python新姿势

    2023-02-13 08:16:22
  • MultipartResolver实现文件上传功能

    2021-06-19 22:38:15
  • Java设计模式中组合模式应用详解

    2022-08-01 01:51:53
  • Java集合系列之ArrayList源码分析

    2023-01-31 03:02:36
  • Java远程连接Linux服务器并执行命令及上传文件功能

    2023-01-28 14:03:31
  • MyBatis通用Mapper和PageHelper的过程详解

    2022-09-29 16:17:03
  • 使用flutter的showModalBottomSheet遇到的坑及解决

    2021-12-07 22:58:29
  • Java实现动态模拟时钟

    2022-07-25 17:35:25
  • 关于Java中HashCode方法的深入理解

    2022-05-28 03:29:33
  • C# 对PDF文档加密、解密(基于Spire.Cloud.SDK for .NET)

    2021-11-23 05:37:26
  • SpringCloud微服务架构升级汇总

    2022-05-04 06:09:19
  • Java泛型机制与反射原理相关知识总结

    2023-11-11 06:02:15
  • Android开发实现ListView异步加载数据的方法详解

    2022-03-26 02:31:57
  • java控制台输入示例分享

    2023-11-28 02:28:05
  • MyBatis-Plus不使用数据库默认值的问题及解决

    2023-11-13 17:37:20
  • asp之家 软件编程 m.aspxhome.com