web-dev-qa-db-ja.com

列挙型メンバーにはどのAttributeTargetを使用する必要がありますか?

次のような列挙型メンバーにIsGPUBasedAttributeを使用したいと思います。

public enum EffectType
{
    [IsGPUBased(true)]
    PixelShader,

    [IsGPUBased(false)]
    Blur
}

しかし、コンパイラは私に使用を許可しません:

[AttributeUsage (AttributeTargets.Enum, AllowMultiple = false)]

使用を列挙型メンバーに制限するための正しいAttributeTarget値は何ですか?

42
Joan Venge

私の知る限り、列挙型定数専用のものはありません。取得できる最も近いものは、おそらく「フィールド」です。これは、クラスまたは構造体のフィールドメンバー(属性の目的で列挙型定数として扱われる)に使用を制限します。

EDIT:コメントから「なぜ」の説明を持ち出すと、列挙型定数はまさにそれであり、そのため、それらの値と使用法は ILに直接埋め込まれています 。したがって、列挙型宣言は、静的定数メンバーを使用して静的クラス定義を作成することと実際にはそれほど違いはありません。

public static class MyEnum
{
    public const int Value1 = 0;
    public const int Value2 = 1;
    public const int Value3 = 2;
    public const int Value4 = 3;        
}

...唯一の違いは、参照クラスではなく値型であるSystem.Enumから派生することです(静的構造体や構築不可能な構造体を作成することはできません)。

59
KeithS

AttributeTargets.Fieldを使用すると、列挙値に属性を使用できます。

[AttributeUsage(AttributeTargets.Field)]
16
Krzysztof

属性を列挙型メンバーでのみ使用できるように指定する方法はありません。正直なところ、このような複数の属性を使用する場合は、独自のEffect(またはEffectType)クラスを作成し、これらを通常のプロパティとして実装することをお勧めします。

例えば、

public class EffectType
{
    public bool IsGpuBased { get; private set; }

    private EffectType(bool isGpuBased)
    {
        IsGpuBased = isGpuBased;
    }

    public static readonly EffectType PixelShader = new EffectType(true);
    public static readonly EffectType Blur = new EffectType(false);
}

このアプローチを採用すると、メタデータ抽出と比較して、読みやすく、パフォーマンスが向上するコードが得られます。

3
Adam Robinson
[AttributeUsage(AttributeTargets.Field)]
1
jsDevia