web-dev-qa-db-ja.com

重複した許可属性を作成する方法

属性クラスから継承したカスタム属性を使用しています。私はこれを次のように使用しています:

    [MyCustomAttribute("CONTROL")]
    [MyCustomAttribute("ALT")]
    [MyCustomAttribute("SHIFT")]
    [MyCustomAttribute("D")]
    public void setColor()
{

}

しかし、「重複した「MyCustomAttribute」属性」エラーが表示されます。
重複した許可属性を作成するにはどうすればよいですか?

87
ebattulga

AttributeUsage属性をAttributeクラスに貼り付け(ええ、それは口いっぱいです)、AllowMultipletrueに設定します。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class MyCustomAttribute: Attribute
168
Anton Gogolev

AttributeUsageAttribute ;-p

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyAttribute : Attribute
{}

ただし、ComponentModel(TypeDescriptor)を使用している場合、メンバーごとに(属性タイプごとに)1つの属性インスタンスのみをサポートすることに注意してください。生の反射は任意の数をサポートしています...

19
Marc Gravell

アントンの解 は正しいですが、 別の落とし穴 があります。

つまり、カスタム属性がTypeIdをオーバーライドしない限り、PropertyDescriptor.GetCustomAttributes()を介してアクセスすると、属性の単一のインスタンスのみが返されます。

12
mcdrewski

デフォルトでは、Attributesは単一のフィールド/プロパティ/などに一度だけ適用されるように制限されています。これは MSDNのAttributeクラスの定義 から確認できます。

[AttributeUsageAttribute(..., AllowMultiple = false)]
public abstract class Attribute : _Attribute

したがって、他の人が指摘したように、すべてのサブクラスは同じように制限され、同じ属性の複数のインスタンスが必要な場合は、AllowMultipletrueに明示的に設定する必要があります。

[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute

複数の使用が可能な属性では、 TypeIdプロパティもオーバーライドする必要があります を使用して、 PropertyDescriptor.Attributes 期待どおりに動作します。これを行う最も簡単な方法は、そのプロパティを実装して属性インスタンス自体を返すことです。

[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
    public override object TypeId
    {
        get
        {
            return this;
        }
    }
}

(この答えを投稿するのは、他の人が間違っているからではなく、これがより包括的/標準的な答えだからです。)

6
Ian Kemp

別の方法として、シーケンスを考慮して属性を再設計することを検討してください。

[MyCustomAttribute(Sequence="CONTROL,ALT,SHIFT,D")]

または

[MyCustomAttribute("CONTROL-ALT-SHIFT-D")]

次に、値を解析して属性を構成します。

この例については、ASP.NET MVCソースコードのAuthorizeAttributeを www.codeplex.com/aspnet で確認してください。

3
tvanfosson

AttributeUsageを追加したら、必ずこのプロパティをAttributeクラスに追加してください

public override object TypeId
{
  get
  {
    return this;
  }
}
2
Axle