2012-01-18 37 views
8

這是最常見的,只有模式到目前爲止,我所看到的:應用C#屬性時允許使用什麼語法?

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

的屬性語法看起來像你調用構造函數。在C#支持可選參數和命名參數之前,屬性的命名參數是唯一可見的區別。

C#編譯器是否允許其他任何內容?像params參數或對象/集合初始值設定項?

參見:Applying Attributes MSDN上

+0

我曾經在一個屬性中放入了一個'string []'初始值設定項。 – JohnL

回答

3

AFAIK,命名參數只允許整數類型。不幸的是,我沒有提及支持這一點,我只是通過我自己的實驗來了解它。

當試圖使用對象initialisers,我從編譯此錯誤:

的屬性參數必須是常量表達式的typeof屬性參數類型的表達或數組創建表達式

雖然這documentation是幾歲,它有我正在尋找的參考信息:

屬性p arameters被限制在 以下類型的恆定值:

  • 簡單類型(布爾,字節,字符,短,整型,長整型,浮點,雙)
  • 的System.Type
  • 枚舉
  • 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中),因此屬性類的成員必須在編譯時確定;因此將屬性參數限制爲常量值。

0

位置參數是必需的,必須出現在任何命名參數;它們對應於屬性構造函數之一的參數。命名參數是可選的,並且對應於屬性的讀/寫屬性。在C++,C#和J#中,爲每個可選參數指定name = value,其中name是屬性的名稱。在Visual Basic中,指定name:= value。

從您提供的鏈接。看起來這些是唯一允許的東西。正如你所提到的,基本上你正在將構造函數與嵌入式屬性初始化邏輯相結合。

3

除了別人所說的之外,我想指出的是,屬性也可以用逗號分隔。

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

這是一個不好的做法;它的可讀性較差。 – Jowen

相關問題