C# 如何创建允许重复的属性

C# 如何创建允许重复的属性,c#,attributes,C#,Attributes,我正在使用从属性类继承的自定义属性。我是这样使用它的: [MyCustomAttribute("CONTROL")] [MyCustomAttribute("ALT")] [MyCustomAttribute("SHIFT")] [MyCustomAttribute("D")] public void setColor() { } 但会显示“重复的'MyCustomAttribute'属性”错误。 如何创建重复的允许属性?将AttributeUsage属性粘贴到属性类上(是的,这很有说服力)

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

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

}
但会显示“重复的'MyCustomAttribute'属性”错误。

如何创建重复的允许属性?

AttributeUsage
属性粘贴到属性类上(是的,这很有说服力),并将
AllowMultiple
设置为
true

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

属性属性-p

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

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

另一种选择是,考虑重新设计属性以允许序列

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

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

有关此示例,请查看ASP.NET MVC源代码中的authorized属性。

是正确的,但有


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

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

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

默认情况下,
属性
s仅限于对单个字段/属性/等应用一次。您可以从以下列表中看到这一点:

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

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class MyCustomAttribute: Attribute
[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute
在允许多个用途的属性上,以确保属性(例如)按预期工作。最简单的方法是实现该属性以返回属性实例本身:

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

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

只是好奇-为什么是“密封”类?Microsoft建议尽可能密封属性类:为什么是密封的?简而言之:使属性查找更快,并且没有其他影响。除了它阻止其他人重用您的代码之外。值得注意的是,DataAnnotations中的验证属性不是密封的,这非常有用,因为它可以创建它们的专门化。@当您不期望或不设计要继承的类时,应该使用Neutrino密封。另外,当继承可能成为错误源时,例如:线程安全实现。甚至可以让
MyCustomAttribute
构造函数获取字符串数组,一个
string[]
,带或不带
params
修饰符。然后可以使用语法
[MyCustom(“CONTROL”、“ALT”、“SHIFT”、“D”)]
(使用
params
)应用它;