【问题标题】:Can I initialize a C# attribute with an array or other variable number of arguments?我可以使用数组或其他可变数量的参数初始化 C# 属性吗?
【发布时间】:2008-11-06 20:42:38
【问题描述】:

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

例如:

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

【问题讨论】:

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

标签: c# attributes


【解决方案1】:

属性将采用一个数组。虽然如果你控制属性,你也可以使用 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 { }

【讨论】:

    【解决方案2】:

    您可以这样做,但它不符合 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】:

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

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

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

    [MyCustomAttribute(3, 4, 5)]

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        如果以下所有陈述都为真,则表达式 E 是 attribute-argument-expression

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

        这是一个例子:

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

        【讨论】:

        • 但请注意 CLS 合规性
        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-12-02
            • 2014-06-17
            • 2021-09-04
            • 2019-10-23
            • 2021-08-20
            相关资源
            最近更新 更多