C# 反射

  • 反射

    Reflection对象用于在运行时获取类型信息。可以访问正在运行的程序的元数据的类位于 System.Reflection 命名空间中。System.Reflection 命名空间包含类,使您获得有关应用程序的信息和动态添加类型,值和对象的应用程序。
  • 反射的应用

    反射具有以下应用程序-
    • 它允许在运行时查看属性信息。
    • 它允许检查装配中的各种类型并实例化这些类型。
    • 它允许后期绑定到方法和属性
    • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。
  • 查看元数据

    在上一章中,我们提到使用反射可以查看属性信息。
    需要初始化System.Reflection类的MemberInfo对象,以发现与类关联的属性。为此,您将目标类的对象定义为-
    
    System.Reflection.MemberInfo info = typeof(MyClass);
    
    以下程序演示了这一点-
    
    using System;
    
    [AttributeUsage(AttributeTargets.All)]
    public class HelpAttribute : System.Attribute {
       public readonly string Url;
       
       public string Topic   // Topic is a named parameter {
          get {
             return topic;
          }
          set {
             topic = value;
          }
       }
       public HelpAttribute(string url)   // url is a positional parameter {
          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属性,并使用反射来读取Rectangle类中的元数据。
    
    using System;
    using System.Reflection;
    
    namespace BugFixApplication {
       //a custom attribute BugFix to be assigned to a class and its members
       [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 {
          //member variables
          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);
             
             //iterating through the attribtues of the Rectangle class
             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);
                }
             }
             
             //iterating through the method attribtues
             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: