这是迄今为止我见过的最常见且唯一的模式:
[AttributeFoo]
[AttributeBar("Hello world!")]
[AttributeBaz(foo=42,bar="Hello world!")]
public class Example {}
属性语法看起来像您正在调用构造函数。在C#支持可选参数和命名参数之前,属性的命名参数是唯一可见的差异。
C#编译器是否允许其他任何内容?像params
参数或对象/集合初始化器一样?
另请参阅:MSDN上的Applying Attributes
答案 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。
从您提供的链接。看起来这是唯一允许的事情。基本上,正如您所提到的,您正在将构造函数与嵌入式属性初始化逻辑相结合。