我可以使用数组或其他数量可变的参数来初始化C#属性吗?


104

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

例如:

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

11
您只是将数组的语法错误。它应该是“ new int [] {3,4,5}”。
David Wengier

Answers:


178

属性将采用数组。尽管可以控制属性,但是也可以使用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 { }

33

您可以做到,但它不符合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,其中仅支持任何属性的单个实例(第一个或最后一个获胜,我不记得是哪个)。


3
注意:多个属性在您的属性上需要AttributeUsage属性。stackoverflow.com/questions/553540/...
russau

23

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

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

然后,您可以像这样使用它:

[MyCustomAttribute(3, 4, 5)]


12

没关系的 根据规范,第17.2节:

如果以下所有语句为真,则表达式E为attribute-argument-expression

  • 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
{
}

5
不过,请注意CLS的合规性
Marc Gravell

4

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

[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }

2

你可以做到的。另一个示例可能是:

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

[MyAttribute("hello", 2, 3.14f)]
class Program
{
    static void Main(string[] args)
    {
    }
}

1

要了解Marc Gravell的答案,是的,您可以定义带有数组参数的属性,但应用带有数组参数的属性不符合CLS。但是,仅使用数组属性定义属性完全符合CLS。

使我意识到这是Json.NET(一个符合CLS的库)具有一个属性类JsonPropertyAttribute,其属性名为ItemConverterParameters的属性是一个对象数组。

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.