应用C#属性时允许使用什么语法?

时间:2012-01-18 21:56:32

标签: c# syntax attributes

这是迄今为止我见过的最常见且唯一的模式:

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

属性语法看起来像您正在调用构造函数。在C#支持可选参数和命名参数之前,属性的命名参数是唯一可见的差异。

C#编译器是否允许其他任何内容?像params参数或对象/集合初始化器一样?

另请参阅:MSDN上的Applying Attributes

3 个答案:

答案 0 :(得分:8)

除了其他人所说的内容之外,我还想指出属性也可以用逗号分隔。

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

答案 1 :(得分:4)

AFAIK,命名参数只允许整数类型。不幸的是,我没有提到支持这一点,我只是通过自己的实验来学习它。

尝试使用对象初始化程序时,我从编译器中收到此错误:

  

属性参数必须是属性参数类型

的常量表达式,typeof表达式或数组创建表达式

虽然这个documentation已经有几年了,但它有我想要的参考信息:

  

属性参数限制为常量值   以下类型:

     
      
  • 简单类型(bool,byte,char,short,int,long,float和double)
  •   
  • 字符串
  •   
  • 的System.Type
  •   
  • enums
  •   
  • object(对象类型的属性参数的参数必须是上述类型之一的常量值。)一维   任何上述类型的数组
  •   

这样可行:

//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

然而这不会:

//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")})]
编辑:只是详细说明,属性构成了应用它们的构造的元数据的一部分(在生成的IL中),因此必须在编译时确定属性类的成员;因此将属性参数限制为常数值。

答案 2 :(得分:1)

  

位置参数是必需的,必须在任何命名参数之前;它们对应于属性构造函数之一的参数。命名参数是可选的,对应于属性的读/写属性。在C ++,C#和J#中,为每个可选参数指定name = value,其中name是属性的名称。在Visual Basic中,指定name:= value。

从您提供的链接。看起来这是唯一允许的事情。基本上,正如您所提到的,您正在将构造函数与嵌入式属性初始化逻辑相结合。