What syntax is allowed when applying C # attributes?

These are the most common and only models that I have seen so far:

[AttributeFoo] [AttributeBar("Hello world!")] [AttributeBaz(foo=42,bar="Hello world!")] public class Example {} 

The attribute syntax looks like you are calling a constructor. And before C # supported optional and named arguments, parameter names for attributes were the only visible difference.

Does the C # compiler provide anything else? How are params arguments or object / collection initializers?

See also: Using Attributes on MSDN

+8
syntax c # attributes
source share
3 answers

AFAIK, named parameters allow only integral types. Unfortunately, I have no references to this; I only found out in my experiments.

When trying to use object initializers, I received this error from the compiler:

The attribute argument must be a constant expression, a typeof expression, or an array creation expression type attribute attribute

Although this documentation is several years old, it does have the background information I was looking for:

Attribute parameters are limited by constant values โ€‹โ€‹of the following types:

  • Simple types (bool, byte, char, short, int, long, float and double)
  • line
  • System.Type
  • enums
  • object (The argument parameter argument of an object of type must be a constant value of one of the above types.) One-dimensional arrays of any of the specified types.

So this works:

 //Test attribute class [AttributeUsage(AttributeTargets.All)] internal class TestAttribute : Attribute { public int[] Something { get; set; } } //Using an array initialiser - an array of integers [TestAttribute(Something = new int[]{1, 2, 3, 4, 5})] public abstract class Something 

If this is not the case:

 //Test person class internal class Person { public string Name { get; set; } public Person(string name) { this.Name = name; } } //Test attribute class [AttributeUsage(AttributeTargets.All)] internal class TestAttribute : Attribute { public IEnumerable<Person> Something { get; set; } } //This won't work as Person is not an integral type [TestAttribute(Something = new Person[]{new Person("James")})] 

EDIT: just to clarify, attributes form part of the metadata for the constructs to which they apply (inside the generated IL), so members of the attribute class must be defined at compile time; therefore, the restriction of attribute parameters to constant values.

+3
source share

In addition to what others have said, I would like to point out that attributes can also be separated by commas.

 [AttributeFoo, AttributeBar("Hello world!"), AttributeBaz(foo=42,bar="Hello world!")] public class Example {} 
+3
source share

Position parameters are necessary and must be presented before any named parameters; they correspond to the parameters of one of the attribute constructors. Named parameters are optional and correspond to attribute read / write properties. In C ++, C #, and J #, provide name = value for each optional parameter, where name is the name of the property. In Visual Basic, specify the name: = value.

From the link you provided. This seems to be the only thing allowed. Basically, you combine the constructor with the built-in property initialization logic, as you mentioned.

0
source share

All Articles