鍍金池/ 教程/ C#/ C#反射
C#屬性(Properties)
C#與Java比較
C#方法
C#枚舉
C#關鍵字
C# StreamReader類
C#不安全代碼
C#文件(I/O)
C#匿名方法
C#線程同步
C# Thread類
C#主線程
C#數(shù)據(jù)類型
C# FileStream類
C#預處理指令
C#繼承
C#循環(huán)
C#決策結構
C#集合
C#反射
C#類型轉(zhuǎn)換
C#泛型
C# StringReader類
C#歷史
C#運算符重載
C#屬性
C#線程實例:Sleep()方法
C#線程示例:優(yōu)先級
C#線程實例:Join()方法
C# BinaryReader類
C#類
C#索引器
C# BinaryWriter類
C#序列化
C#常量和文字
C#程序結構
C#封裝
C#事件
C#可空類型(nullable)
C#基本語法
C#異常處理
C#教程
C#接口
C# System.IO命名空間
C#線程命名實例
C# StringWriter類
C#線程實例
C#數(shù)組
C#正則表達式
C#命名空間
C#反序列化
C#與C++比較
C# TextWriter類
C#多線程
C#字符串
C#是什么?
C#變量
C# FileInfo類
C#線程實例:Abort()方法
C#結構體
C#運算符
C#入門程序
C#多線程生命周期
C# TextReader類
C# DirectoryInfo類
C#委托

C#反射

Reflection對象用于在運行時獲取類型信息??梢栽L問正在運行的程序的元數(shù)據(jù)的類在System.Reflection命名空間中。

System.Reflection命名空間包含允許獲取有關應用程序的信息的類,并向應用程序動態(tài)添加類型,值和對象。

反射有以下應用:

  • 它允許在運行時查看屬性信息。
  • 它允許檢查裝配中的各種類型并實例化這些類型。
  • 它允許后期綁定到方法和屬性。
  • 它允許在運行時創(chuàng)建新的類型,可使用這些類型執(zhí)行一些任務。

查看元數(shù)據(jù)

我們在上一章中提到使用反射可以查看屬性信息。

需要初始化System.Reflection類的MemberInfo對象,以發(fā)現(xiàn)與類相關聯(lián)的屬性。可將目標類的對象定義為:

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

例子

在這個例子中,我們使用上一章創(chuàng)建的DeBugInfo屬性,并使用反射來讀取Rectangle類中的元數(shù)據(jù)。

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, "Sukida", "12/8/2017", Message = "Return type mismatch")]
   [DeBugInfo(49, "Maxsu", "10/10/2017", 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, "Sukida", "19/10/2017", Message = "Return type mismatch")]
      public double GetArea()
      {
         return length * width;
      }
      [DeBugInfo(56, "Sukida", "19/10/2017")]
      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(14.5, 17.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();
      }
   }
}

當上述代碼被編譯并執(zhí)行時,它產(chǎn)生以下結果:

Length: 14.5
Width: 17.5
Area: 253.75
Bug no: 45
Developer: Sukida
Last Reviewed: 12/8/2017
Remarks: Return type mismatch
Bug no: 49
Developer: Maxsu
Last Reviewed: 10/10/2017
Remarks: Unused variable
Bug no: 55, for Method: GetArea
Developer: Sukida
Last Reviewed: 19/10/2017
Remarks: Return type mismatch
Bug no: 56, for Method: Display
Developer: Sukida
Last Reviewed: 19/10/2017
Remarks:

上一篇:C#類下一篇:C#屬性