How to create duplicate allowed attributes

I'm using a custom attribute inherited from an attribute class. I'm using it like this:

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


}

But the "Duplicate 'MyCustomAttribute' attribute" error is shown.
How can I create a duplicate allowed attribute?

39054 次浏览

Stick an AttributeUsage attribute onto your Attribute class (yep, that's mouthful) and set AllowMultiple to true:

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

AttributeUsageAttribute;-p

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

Note, however, that if you are using ComponentModel (TypeDescriptor), it only supports one attribute instance (per attribute type) per member; raw reflection supports any number...

作为替代方案,考虑重新设计属性以允许一个序列。

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

或者

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

然后解析这些值以配置属性。

有关这方面的示例,请在 Www.codeplex.com/aspnet查看 ASP.NET MVC 源代码中的 AuthorizeAttribute。

Anton's solution is correct, but there is 又抓到你了.

简而言之,除非您的自定义属性覆盖 TypeId,否则通过 PropertyDescriptor.GetCustomAttributes()访问它将只返回属性的一个实例。

添加 AttributeUse 之后,请确保将此属性添加到 Attribute 类中

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

By default, Attributes are limited to being applied only once to a single field/property/etc. You can see this from the 在 MSDN 上定义 Attribute:

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

因此,正如其他人所指出的,所有子类都受到相同方式的限制,如果需要同一属性的多个实例,则需要显式地将 AllowMultiple设置为 true:

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

对于允许多种用法的属性,还应重写 TypeId属性可以确保诸如 PropertyDescriptor.Attributes之类的属性按预期的方式工作。最简单的方法是实现该属性以返回属性实例本身:

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

(发布这个答案并不是因为其他人错了,而是因为这是一个更全面/规范的答案。)