工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C#属性:メタデータでコードを拡張する完全ガイド

属性(Attribute)とは、プログラム内のクラス、メソッド、構造体、列挙子、アセンブリなどのさまざまな要素の動作についてランタイムに情報を伝えるための宣言的なタグです。角括弧([ ])で要素の上に配置することで、プログラムに宣言的な情報を追加できます。

属性は、コンパイラへの指示、コメント、説明、メソッド、クラスなどのメタデータをプログラムに追加するために使用されます。.NET Frameworkには2種類の属性があります:定義済み属性とカスタム属性です。

属性の指定構文

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

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

定義済み属性

.NET Frameworkには3つの定義済み属性があります。

AttributeUsage属性

定義済み属性AttributeUsageは、カスタム属性クラスをどのように使用できるかを記述します。属性を適用できるアイテムの種類を指定します。

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

パラメータ:

AttributeUsageの例

[AttributeUsage(
    AttributeTargets.Class 
  | AttributeTargets.Constructor 
  | AttributeTargets.Field 
  | AttributeTargets.Method 
  | AttributeTargets.Property,
    AllowMultiple = true
)]
public class MyCustomAttribute : Attribute { }

Conditional属性

この定義済み属性は、指定されたプリプロセッサ識別子に依存して実行される条件付きメソッドをマークします。DebugやTraceなどの指定値に応じて、メソッド呼び出しの条件付きコンパイルを行います。例えば、コードのデバッグ中に変数の値を表示するのに使用します。

[Conditional("DEBUG")]

Conditional属性の例

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

実行結果(DEBUG定義時):

In Main function
In Function 1
In Function 2

#define DEBUGを削除またはコメントアウトすると、Messageメソッドへのすべての呼び出しがコンパイラによって無視され、出力は何もなくなります。メソッド自体も呼び出されません(ILに含まれない)。

Obsolete属性

この定義済み属性は、使用すべきでないプログラムエンティティをマークします。コンパイラに特定の対象要素を破棄するよう指示できます。例えば、クラスで新しいメソッドを使用するようになったが、古いメソッドをクラスに残しておきたい場合、古いメソッドをObsoleteとしてマークし、新しいメソッドを使用するようメッセージを表示できます。

構文

[Obsolete(message)]
[Obsolete(message, isError)]

Obsolete属性の例

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つのステップがあります。

  1. カスタム属性の宣言
  2. カスタム属性の構築
  3. ターゲットプログラム要素へのカスタム属性の適用
  4. リフレクションによる属性へのアクセス

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

カスタム属性の宣言

新しいカスタム属性はSystem.Attributeクラスから派生させる必要があります。

[AttributeUsage(
    AttributeTargets.Class 
  | AttributeTargets.Constructor 
  | AttributeTargets.Field 
  | AttributeTargets.Method 
  | AttributeTargets.Property,
    AllowMultiple = true
)]
public class DeBugInfo : System.Attribute

カスタム属性の構築

DeBugInfoというカスタム属性を構築し、プログラムのデバッグで得られた情報を格納するとします。以下の情報を格納します。

DeBugInfoクラスは最初の3つの情報用に3つのプライベートプロパティ、メッセージ用にパブリックプロパティを持ちます。したがって、バグ番号、開発者名、レビュー日は位置指定パラメータ、メッセージはオプション/名前付きパラメータとなります。

すべての属性には少なくとも1つのコンストラクタが必要です。位置指定パラメータはコンストラクタで渡します。

[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 => bugNo;
    public string Developer => developer;
    public string LastReview => lastReview;
    public string Message { get => 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() => 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());
    }
}

よく使用される標準属性

属性用途
[Serializable]型をシリアライズ可能にマーク
[DataContract]/[DataMember]WCF/シリアライゼーション用データ契約
[JsonPropertyName]System.Text.Jsonでのプロパティ名指定
[Required]/[StringLength]等データ検証(DataAnnotations)
[DllImport]非管理DLL関数のインポート
[CallerMemberName]/[CallerFilePath]/[CallerLineNumber]呼び出し元情報の自動取得
[DoesNotReturn]/[NotNull]等静的解析ヒント(C# 8.0+)

ベストプラクティス

C言語

  1. AgCu20 合金:23°C における包括的な機械的・熱的特性
  2. 合金 15CDV6(DIN 1.7734):高強度・高靭性、容易な溶接性
  3. DIN 1.7734 5 - 15CDV6合金:高強度、高靭性、容易な溶接性
  4. 15CDV6合金(DIN 1.7734) - 高強度、容易な溶接性、優れた靭性
  5. PtNi10 合金:包括的な機械的・熱的特性
  6. PtIr10 白金-イリジウム合金:高強度・高温材料
  7. Corroplastプレート – 精密機械加工向け高性能耐食鋼
  8. X46 AM FCE:重要パイプライン用途向け高性能API 5L鋼
  9. フェロ・チタニット® クロモニ – 高強度、非磁性チタン合金
  10. C#のヌル許容型:null値を安全に扱う完全ガイド
  11. Java 8 Optional完全ガイド:実践的なNull安全コードの書き方