Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

attributes

People also ask

Can we initialize variable in C?

Unlike PASCAL, in C variables may be initialized with a value when they are declared. Consider the following declaration, which declares an integer variable count which is initialized to 10. Lets examine what the default value a variable is assigned when its declared.

What does it mean to initialize in C?

In computer programming, initialization (or initialisation) is the assignment of an initial value for a data object or variable. The manner in which initialization is performed depends on the programming language, as well as the type, storage class, etc., of an object to be initialized.

What happens when you initialize a variable in C?

Declaring & initializing C variable: Variables should be declared in the C program before to use. Memory space is not allocated for a variable while declaration. It happens only on variable definition. Variable initialization means assigning a value to the variable.


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

You can do it, but it isn't CLS compliant:

[assembly: CLSCompliant(true)]

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

Shows:

Warning 1   Arrays as attribute arguments is not CLS-compliant

For regular reflection usage, it may be preferable to have multiple attributes, i.e.

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

However, this won't work with TypeDescriptor/PropertyDescriptor, where only a single instance of any attribute is supported (either the first or last wins, I can't recall which).


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)]


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