114

是否可以创建一个可以用可变数量的参数初始化的属性?

例如:

[MyCustomAttribute(new int[3,4,5])]  // this doesn't work
public MyClass ...
4

7 回答 7

191

属性将采用一个数组。虽然如果你控制属性,你也可以使用params(这对消费者来说更好,IMO):

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(params int[] values) {
       this.Values = values;
    }
}

[MyCustomAttribute(3, 4, 5)]
class MyClass { }

您的数组创建语法恰好是关闭的:

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(int[] values) {
        this.Values = values;
    }
}

[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }
于 2008-11-06T20:51:14.050 回答
40

您可以这样做,但它不符合 CLS:

[assembly: CLSCompliant(true)]

class Foo : Attribute
{
    public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}

显示:

Warning 1   Arrays as attribute arguments is not CLS-compliant

对于常规反射的使用,最好有多个属性,即

[Foo("abc"), Foo("def")]

但是,这不适用于TypeDescriptor/ PropertyDescriptor,其中仅支持任何属性的单个实例(第一次或最后一次获胜,我不记得是哪个)。

于 2008-11-06T21:50:21.590 回答
24

尝试像这样声明构造函数:

public class MyCustomAttribute : Attribute
{
    public MyCustomAttribute(params int[] t)
    {
    }
}

然后你可以像这样使用它:

[MyCustomAttribute(3, 4, 5)]

于 2008-11-06T20:49:50.387 回答
13

那应该没问题。从规范,第 17.2 节:

如果以下所有语句都为真,则表达式 E 是属性参数表达式:

  • E 的类型是属性参数类型(§17.1.3)。
  • 在编译时, E 的值可以解析为以下之一:
    • 一个常数值。
    • 一个 System.Type 对象。
    • 属性参数表达式的一维数组。

这是一个例子:

using System;

[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class SampleAttribute : Attribute
{
    public SampleAttribute(int[] foo)
    {
    }
}

[Sample(new int[]{1, 3, 5})]
class Test
{
}
于 2008-11-06T20:49:08.657 回答
5

是的,但是您需要初始化您传入的数组。这是我们单元测试中的一个行测试示例,它测试了可变数量的命令行选项;

[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
于 2008-11-06T20:48:45.757 回答
2

你可以这样做。另一个例子可能是:

class MyAttribute: Attribute
{
    public MyAttribute(params object[] args)
    {
    }
}

[MyAttribute("hello", 2, 3.14f)]
class Program
{
    static void Main(string[] args)
    {
    }
}
于 2008-11-06T20:50:49.027 回答
2

要背负 Marc Gravell 的回答,是的,您可以使用数组参数定义属性,但应用具有数组参数的属性不符合 CLS。但是,仅使用数组属性定义属性就完全符合 CLS。

让我意识到这一点的是 Json.NET,一个符合 CLS 的库,有一个属性类 JsonPropertyAttribute 和一个名为 ItemConverterParameters 的属性,它是一个对象数组。

于 2016-03-18T14:39:50.970 回答