如何创建重复的允许属性


96

我正在使用从属性类继承的自定义属性。我正在这样使用它:

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

}

但是显示“重复的'MyCustomAttribute'属性”错误。
如何创建重复的允许属性?

Answers:


184

AttributeUsage属性粘贴到Attribute类上(是的,这很麻烦)并设置AllowMultipletrue

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

6
只是好奇-为什么要进行“密封”课程?
Tomas Aschan

18
Microsoft建议尽可能地密封属性类:msdn.microsoft.com/en-us/library/2ab31zeh.aspx
Anton Gogolev

3
为什么要密封?简而言之:使属性查找更快,并且没有其他影响。
Noel Widmer

除了它阻止其他任何人重用您的代码。值得一提的是,DataAnnotations中的验证属性不是密封的,这非常有用,因为它可以创建它们的特殊化。
Neutrino,

每当您不希望或没有设计要继承的类时,都应使用@Neutrino密封。另外,当继承可能成为错误的来源时,例如:线程安全的实现。
弗朗西斯科·内托

20

AttributeUsageAttribute ;-p

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

但是请注意,如果使用的是ComponentModel(TypeDescriptor),则每个成员仅支持一个属性实例(每种属性类型)。原始反射支持任何数量...


13

安东的解决方案是正确的,但还有另一个陷阱

简而言之,除非您的自定义属性重写TypeId,否则通过其访问PropertyDescriptor.GetCustomAttributes()将仅返回属性的单个实例。


但是它可以通过以下方式工作:var customAtt = propertyInfo.GetCustomAttributes <MyCustomAttribute>();
oo_dev

8

默认情况下,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;
        }
    }
}

(发布此答案不是因为其他答案是错误的,而是因为这是更全面/规范的答案。)


3

或者,考虑重新设计属性以允许序列。

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

要么

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

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

有关此示例,请访问www.codeplex.com/aspnet上的 ASP.NET MVC源代码中的AuthorizeAttribute 。


3
甚至有可能让MyCustomAttribute构造函数采用带有或不带有修饰符的字符串数组 a 。然后可以将其与语法一起使用(使用)。string[]params[MyCustom("CONTROL", "ALT", "SHIFT", "D")]params
Jeppe Stig Nielsen

2

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

public override object TypeId
{
  get
  {
    return this;
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.