Can I initialize a C# attribute with an array or other variable number of arguments?

后端 未结 7 2174
生来不讨喜
生来不讨喜 2020-11-28 05:56

Is it possible to create an attribute that can be initialized with a variable number of arguments?

For example:

[MyCustomAttribute(new int[3,4,5])]           


        
相关标签:
7条回答
  • 2020-11-28 06:21

    Yes, but you need to initialize the array that you are passing in. Here is an example from a row test in our unit tests that tests a variable number of command line options;

    [Row( new[] { "-l", "/port:13102", "-lfsw" } )]
    public void MyTest( string[] args ) { //... }
    
    0 讨论(0)
  • 2020-11-28 06:27

    Try declaring the constructor like this:

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

    Then you can use it like:

    [MyCustomAttribute(3, 4, 5)]

    0 讨论(0)
  • 2020-11-28 06:27

    To piggy back on Marc Gravell's answer, yes you can define an attribute with array parameters but applying an attribute with an array parameter is not CLS-compliant. However just defining an attribute with an array property is perfectly CLS-compliant.

    What made me realize this was that Json.NET, a CLS-compliant library, has an attribute class JsonPropertyAttribute with a property named ItemConverterParameters that's an array of objects.

    0 讨论(0)
  • 2020-11-28 06:41

    Attributes will take an array. Though if you control the attribute, you can also use params instead (which is nicer to consumers, IMO):

    class MyCustomAttribute : Attribute {
        public int[] Values { get; set; }
    
        public MyCustomAttribute(params int[] values) {
           this.Values = values;
        }
    }
    
    [MyCustomAttribute(3, 4, 5)]
    class MyClass { }
    

    Your syntax for array creation just happens to be off:

    class MyCustomAttribute : Attribute {
        public int[] Values { get; set; }
    
        public MyCustomAttribute(int[] values) {
            this.Values = values;
        }
    }
    
    [MyCustomAttribute(new int[] { 3, 4, 5 })]
    class MyClass { }
    
    0 讨论(0)
  • 2020-11-28 06:41

    That should be okay. From the spec, section 17.2:

    An expression E is an attribute-argument-expression if all of the following statements are true:

    • The type of E is an attribute parameter type (§17.1.3).
    • At compile-time, the value of E can be resolved to one of the following:
      • A constant value.
      • A System.Type object.
      • A one-dimensional array of attribute-argument-expressions.

    Here's an example:

    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
    {
    }
    
    0 讨论(0)
  • 2020-11-28 06:41

    You can do that. Another example could be:

    class MyAttribute: Attribute
    {
        public MyAttribute(params object[] args)
        {
        }
    }
    
    [MyAttribute("hello", 2, 3.14f)]
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
    
    0 讨论(0)
提交回复
热议问题