C# - 屬性



**屬性**是宣告性標籤,用於向執行時傳達有關各種元素(如類、方法、結構、列舉器、程式集等)在程式中的行為的資訊。您可以使用屬性向程式新增宣告性資訊。宣告性標籤由放置在它所用元素上方的方括號([ ])表示。

屬性用於新增元資料,例如編譯器指令和其他資訊,例如註釋、描述、方法和類到程式中。.Net Framework 提供兩種型別的屬性:預定義屬性和自定義構建屬性。

指定屬性

指定屬性的語法如下:

[attribute(positional_parameters, name_parameter = value, ...)]
element

屬性的名稱及其值在方括號內指定,位於應用屬性的元素之前。位置引數指定必要資訊,而命名引數指定可選資訊。

預定義屬性

.Net Framework 提供三個預定義屬性:

  • AttributeUsage
  • Conditional
  • Obsolete

AttributeUsage

預定義屬性AttributeUsage描述瞭如何使用自定義屬性類。它指定可以將屬性應用於哪些型別的專案。

指定此屬性的語法如下:

[AttributeUsage (
   validon,
   AllowMultiple = allowmultiple,
   Inherited = inherited
)]

其中,

  • 引數validon指定可以放置屬性的語言元素。它是列舉器AttributeTargets值的組合。預設值為AttributeTargets.All

  • 引數allowmultiple(可選)為此屬性的AllowMultiple屬性提供值,一個布林值。如果為真,則屬性是多用途的。預設為假(單一用途)。

  • 引數inherited(可選)為此屬性的Inherited屬性提供值,一個布林值。如果為真,則派生類將繼承該屬性。預設值為假(未繼承)。

例如,

[AttributeUsage(
   AttributeTargets.Class |
   AttributeTargets.Constructor |
   AttributeTargets.Field |
   AttributeTargets.Method |
   AttributeTargets.Property, 
   AllowMultiple = true)]

Conditional

此預定義屬性標記一個條件方法,其執行取決於指定的預處理識別符號。

它根據指定的值(例如DebugTrace)導致方法呼叫的條件編譯。例如,它在除錯程式碼時顯示變數的值。

指定此屬性的語法如下:

[Conditional(
   conditionalSymbol
)]

例如,

[Conditional("DEBUG")]

以下示例演示了該屬性:

#define DEBUG
using System;
using System.Diagnostics;

public class Myclass {
   [Conditional("DEBUG")]
   
   public static void Message(string msg) {
      Console.WriteLine(msg);
   }
}
class Test {
   static void function1() {
      Myclass.Message("In Function 1.");
      function2();
   }
   static void function2() {
      Myclass.Message("In Function 2.");
   }
   public static void Main() {
      Myclass.Message("In Main function.");
      function1();
      Console.ReadKey();
   }
}

當編譯並執行上述程式碼時,它會產生以下結果:

In Main function
In Function 1
In Function 2

Obsolete

此預定義屬性標記不應使用的程式實體。它使您能夠通知編譯器丟棄特定目標元素。例如,當在類中使用新方法時,如果您仍然希望在類中保留舊方法,則可以透過顯示一條訊息來將其標記為已過時,該訊息應使用新方法而不是舊方法。

指定此屬性的語法如下:

[Obsolete (
   message
)]

[Obsolete (
   message,
   iserror
)]

其中,

  • 引數message是一個字串,描述專案已過時的原因以及應使用什麼代替。

  • 引數iserror是一個布林值。如果其值為真,則編譯器應將專案的用法視為錯誤。預設值為假(編譯器生成警告)。

以下程式演示了這一點:

using System;

public class MyClass {
   [Obsolete("Don't use OldMethod, use NewMethod instead", true)]
   
   static void OldMethod() {
      Console.WriteLine("It is the old method");
   }
   static void NewMethod() {
      Console.WriteLine("It is the new method"); 
   }
   public static void Main() {
      OldMethod();
   }
}

當您嘗試編譯程式時,編譯器會給出錯誤訊息,指出:

 Don't use OldMethod, use NewMethod instead

建立自定義屬性

.Net Framework 允許建立自定義屬性,這些屬性可用於儲存宣告性資訊,並在執行時檢索。此資訊可以與任何目標元素相關聯,具體取決於設計標準和應用程式需求。

建立和使用自定義屬性涉及四個步驟:

  • 宣告自定義屬性
  • 構造自定義屬性
  • 將自定義屬性應用於目標程式元素
  • 透過反射訪問屬性

最後一步涉及編寫一個簡單的程式來讀取元資料以查詢各種註釋。元資料是有關資料的元資料或用於描述其他資料的資訊。此程式應使用反射在執行時訪問屬性。我們將在下一章中討論這一點。

宣告自定義屬性

新的自定義屬性應從System.Attribute類派生。例如,

//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

在前面的程式碼中,我們聲明瞭一個名為DeBugInfo的自定義屬性。

構造自定義屬性

讓我們構造一個名為DeBugInfo的自定義屬性,它儲存透過除錯任何程式獲得的資訊。讓它儲存以下資訊:

  • 錯誤的程式碼編號
  • 識別錯誤的開發人員的姓名
  • 程式碼上次審查的日期
  • 用於儲存開發人員備註的字串訊息

DeBugInfo類具有三個私有屬性用於儲存前三個資訊以及一個公共屬性用於儲存訊息。因此,錯誤編號、開發人員姓名和審查日期是DeBugInfo類的位置引數,而訊息是可選或命名引數。

每個屬性都必須至少有一個建構函式。位置引數應透過建構函式傳遞。以下程式碼顯示了DeBugInfo類:

//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());
   }
}

在下一章中,我們將使用反射類物件檢索屬性資訊。

廣告