C#-属性

アン attributeは、プログラム内のクラス、メソッド、構造、列挙子、アセンブリなどのさまざまな要素の動作に関する情報をランタイムに伝達するために使用される宣言型タグです。属性を使用して、宣言型情報をプログラムに追加できます。宣言型タグは、使用される要素の上に配置された角かっこ([])で表されます。

属性は、コンパイラ命令などのメタデータや、コメント、説明、メソッド、クラスなどの他の情報をプログラムに追加するために使用されます。.Net Frameworkは、事前定義された属性とカスタムビルドされた属性の2種類の属性を提供します。

属性の指定

属性を指定するための構文は次のとおりです-

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

属性の名前とその値は、属性が適用される要素の前の角括弧内に指定されます。位置パラメーターは重要な情報を指定し、名前パラメーターはオプションの情報を指定します。

事前定義された属性

.Net Frameworkは、3つの事前定義された属性を提供します-

  • AttributeUsage
  • Conditional
  • Obsolete

AttributeUsage

事前定義された属性 AttributeUsageカスタム属性クラスの使用方法について説明します。属性を適用できるアイテムのタイプを指定します。

この属性を指定するための構文は次のとおりです-

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

どこ、

  • パラメーターvalidonは、属性を配置できる言語要素を指定します。これは、列挙子AttributeTargetsの値の組み合わせです。デフォルト値はAttributeTargets.Allです。

  • パラメータallowmultiple(オプション)は、この属性のAllowMultipleプロパティの値であるブール値を提供します。これが当てはまる場合、属性は多目的です。デフォルトはfalse(シングルユース)です。

  • 継承されたパラメーター(オプション)は、この属性の継承されたプロパティの値であるブール値を提供します。trueの場合、属性は派生クラスに継承されます。デフォルト値はfalseです(継承されません)。

例えば、

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

条件付き

この事前定義された属性は、実行が指定された前処理識別子に依存する条件付きメソッドをマークします。

次のような指定された値に応じて、メソッド呼び出しの条件付きコンパイルが発生します。 Debug または Trace。たとえば、コードのデバッグ中に変数の値を表示します。

この属性を指定するための構文は次のとおりです-

[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 (
   message
)]

[Obsolete (
   message,
   iserror
)]

どこ、

  • パラメータメッセージは、アイテムが廃止された理由と代わりに何を使用するかを説明する文字列です。

  • パラメータiserrorは、ブール値です。その値がtrueの場合、コンパイラーはアイテムの使用をエラーとして扱う必要があります。デフォルト値はfalseです(コンパイラーは警告を生成します)。

次のプログラムはこれを示しています-

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を使用すると、宣言型情報を格納するために使用でき、実行時に取得できるカスタム属性を作成できます。この情報は、設計基準とアプリケーションのニーズに応じて、任意のターゲット要素に関連付けることができます。

カスタム属性の作成と使用には、4つのステップが含まれます-

  • カスタム属性の宣言
  • カスタム属性の構築
  • ターゲットプログラム要素にカスタム属性を適用します
  • リフレクションを介した属性へのアクセス

最後のステップでは、メタデータを読み取ってさまざまな表記を見つけるための簡単なプログラムを作成します。メタデータは、データに関するデータ、または他のデータを記述するために使用される情報です。このプログラムは、実行時に属性にアクセスするためにリフレクションを使用する必要があります。これについては、次の章で説明します。

カスタム属性の宣言

新しいカスタム属性は、 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のクラスは、最初の3つの情報やメッセージを格納するためのパブリックプロパティを格納するための3つのプライベートプロパティがあります。したがって、バグ番号、開発者の名前、およびレビューの日付はDeBugInfoクラスの位置パラメーターであり、メッセージはオプションまたは名前付きパラメーターです。

各属性には、少なくとも1つのコンストラクターが必要です。位置パラメーターはコンストラクターを介して渡される必要があります。次のコードは、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());
   }
}

次の章では、Reflectionクラスオブジェクトを使用して属性情報を取得します。