🦁

AttributeUsageの使い方を初心者向けに詳細解説

2024/11/30に公開

C#の属性(Attribute)は、コード要素にメタデータを付加する強力な機能です。AttributeUsageは、カスタム属性を定義する際に、その属性が適用可能な対象や適用ルールを制御するために使用します。

この記事では、身近な「動物」や「犬」を題材に、AttributeUsageの使い方を初心者向けにわかりやすく解説します。また、AttributeUsageの詳細設定を表形式でまとめ、理解を深めます。


目次

  1. 属性(Attribute)とは
  2. AttributeUsageとは
  3. カスタム属性の作成と適用
    • ステップ1: カスタム属性の定義
    • ステップ2: 属性の適用
    • ステップ3: 属性を利用した処理の実装
  4. AttributeUsageの詳細設定
    • AttributeTargetsの詳細(表形式)
    • InheritedAllowMultipleの詳細(表形式)
  5. 実践例
    • 複数の属性適用と継承
  6. まとめ
  7. 参考資料

1. 属性(Attribute)とは

属性は、プログラム要素に追加情報を付加するための仕組みです。リフレクションを用いてランタイム時に情報を取得し、動的な処理を行うことができます。

[Serializable]
public class Animal
{
    // このクラスはシリアル化可能であることを示します
}

2. AttributeUsageとは

AttributeUsageは、カスタム属性を定義する際に、その属性の適用対象や適用ルールを指定するための属性です。

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class MyCustomAttribute : Attribute
{
    // カスタム属性の定義
}

3. カスタム属性の作成と適用

ステップ1: カスタム属性の定義

以下では、動物クラスに特定の情報を付加するための属性を作成します。

using System;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true)]
public class AnimalInfoAttribute : Attribute
{
    public string Description { get; }
    public string Habitat { get; }

    public AnimalInfoAttribute(string description, string habitat)
    {
        Description = description;
        Habitat = habitat;
    }
}
  • AttributeTargets.Class | AttributeTargets.Property: この属性はクラスとプロパティに適用可能。
  • AllowMultiple = true: 同じ要素に複数回適用できる。

ステップ2: 属性の適用

定義した属性をクラスやプロパティに適用します。

[AnimalInfo("家庭で飼育される動物", "家")]
public class Dog
{
    [AnimalInfo("犬の名前を表すプロパティ", "該当なし")]
    public string Name { get; set; }

    [AnimalInfo("犬の年齢を表すプロパティ", "該当なし")]
    public int Age { get; set; }
}
  • 説明をより明確に: "Dog's age" や "Dog's name" ではなく、日本語でわかりやすい説明を付加しました。

ステップ3: 属性を利用した処理の実装

リフレクションを用いて、属性の情報を取得します。

using System;
using System.Reflection;

public class AttributeReader
{
    public static void DisplayAnimalInfo(Type animalType)
    {
        // クラスの属性を取得
        var classAttributes = animalType.GetCustomAttributes<AnimalInfoAttribute>();

        foreach (var attr in classAttributes)
        {
            Console.WriteLine($"クラス名: {animalType.Name}");
            Console.WriteLine($"説明: {attr.Description}");
            Console.WriteLine($"生息地: {attr.Habitat}");
        }

        // プロパティの属性を取得
        var properties = animalType.GetProperties();

        foreach (var prop in properties)
        {
            var propAttributes = prop.GetCustomAttributes<AnimalInfoAttribute>();

            foreach (var attr in propAttributes)
            {
                Console.WriteLine($"プロパティ名: {prop.Name}");
                Console.WriteLine($"説明: {attr.Description}");
                Console.WriteLine($"生息地: {attr.Habitat}");
            }
        }
    }
}

実行例:

public class Program
{
    public static void Main()
    {
        AttributeReader.DisplayAnimalInfo(typeof(Dog));
    }
}

出力結果:

クラス名: Dog
説明: 家庭で飼育される動物
生息地: 家
プロパティ名: Name
説明: 犬の名前を表すプロパティ
生息地: 該当なし
プロパティ名: Age
説明: 犬の年齢を表すプロパティ
生息地: 該当なし

4. AttributeUsageの詳細設定

AttributeUsageには、カスタム属性の適用対象や適用ルールを詳細に設定するための引数があります。以下に、それらを表形式でまとめます。

4.1 AttributeTargetsの詳細(必須)

属性を適用できるプログラム要素を指定します。複数の対象を指定する場合はビット演算子 | を使用します。

AttributeTargets の値 説明
Assembly アセンブリ全体
Module モジュール
Class クラス
Struct 構造体
Enum 列挙型
Constructor コンストラクター
Method メソッド
Property プロパティ
Field フィールド
Event イベント
Interface インターフェース
Parameter パラメーター
Delegate デリゲート
ReturnValue メソッドの戻り値
GenericParameter ジェネリックパラメーター

例:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
public class SampleAttribute : Attribute
{
    // この属性はメソッドとプロパティに適用可能
}

4.2 InheritedAllowMultipleの詳細

引数 説明 デフォルト値
Inherited 属性が派生クラスやメンバーに継承されるか true
AllowMultiple 同じ要素に属性を複数回適用できるか false

Inheritedの詳細

説明
true 属性が派生クラスや派生メンバーに継承される
false 属性が派生クラスや派生メンバーに継承されない

例:

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class NonInheritedAttribute : Attribute
{
    // この属性は派生クラスに継承されません
}

AllowMultipleの詳細

説明
true 同じプログラム要素に属性を複数回適用できる
false 同じプログラム要素に属性を複数回適用できない(デフォルト)

例:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MultiUseAttribute : Attribute
{
    // この属性は同じメソッドに複数回適用できます
}

5. 実践例

5.1 複数の属性を同じ要素に適用

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class SkillAttribute : Attribute
{
    public string SkillName { get; }

    public SkillAttribute(string skillName)
    {
        SkillName = skillName;
    }
}

[Skill("吠える")]
[Skill("物を取ってくる")]
[Skill("お座りをする")]
public class Dog
{
    // 犬は複数のスキルを持っています
}

属性の情報を取得する:

var skills = typeof(Dog).GetCustomAttributes<SkillAttribute>();
foreach (var skill in skills)
{
    Console.WriteLine($"スキル: {skill.SkillName}");
}

出力結果:

スキル: 吠える
スキル: 物を取ってくる
スキル: お座りをする

5.2 属性の継承

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class AnimalAttribute : Attribute
{
    public string Kingdom { get; }

    public AnimalAttribute(string kingdom)
    {
        Kingdom = kingdom;
    }
}

[Animal("動物界")]
public class Animal
{
    // 基本的な動物クラス
}

public class Dog : Animal
{
    // 犬クラスはAnimalAttributeを継承します
}

属性の情報を取得する:

var animalAttr = typeof(Dog).GetCustomAttribute<AnimalAttribute>();
Console.WriteLine($"界: {animalAttr.Kingdom}");

出力結果:

界: 動物界

6. まとめ

  • **属性(Attribute)**は、コード要素にメタデータを付加するための仕組み。

  • **AttributeUsage**は、カスタム属性の適用対象や適用ルールを定義するための属性。

  • 主な引数:

    • AttributeTargets(必須): 属性を適用できる要素を指定。
    • Inherited(省略可能): 属性が継承されるかを指定(デフォルトはtrue)。
    • AllowMultiple(省略可能): 同じ要素に複数回適用できるかを指定(デフォルトはfalse)。
  • 実践的な活用:

    • カスタム属性を定義し、AttributeUsageで適用ルールを設定。
    • リフレクションを用いて、ランタイム時に属性情報を取得・利用。

7. 参考資料


Discussion