2011-06-06 108 views
15

可以同時組合一個List初始值設定項和對象初始值設定項嗎? 考慮下面的類定義:組合列表初始值設定項和對象初始化項

class MyList : List<int> 
{ 
    public string Text { get; set; } 
} 

// we can do this 
var obj1 = new MyList() { Text="Hello" }; 

// we can also do that 
var obj2 = new MyList() { 1, 2, 3 }; 

// but this one doesn't compile 
//var obj3 = new MyList() { Text="Hello", 1, 2, 3 }; 

這是由設計或只是一個bug或C#編譯器功能缺失?

回答

25

否,從C#規範的部分7.6.10看的定義,一個object-or-collection-initializer表達是要麼一個object-initializer一個collection-initializer

object-initializer是由多個的member-initializer S,其中的每一個的形式initializer = initializer-value的而collection-initializer由多個的element-initializer S,其中的每一個是一個non-assigment-expression

因此,它看起來像是通過設計 - 可能是爲了簡單起見。我不能說我曾經想要這樣做,說實話。 (我通常不會從List<int>派生入手 - 我撰寫它來代替。)我真的很討厭看到:

var obj3 = new MyList { 1, 2, Text = "Hello", 3, 4 }; 

編輯:如果你真的,真的要啓用此功能,您可以把這個類:

class MyList : List<int> 
{ 
    public string Text { get; set; } 
    public MyList Values { get { return this; } } 
} 

在這一點上,你可以寫:

var obj3 = new MyList { Text = "Hello", Values = { 1, 2, 3, 4 } }; 
+0

該規範應該強制對象初始化部分和列表初始化部分此起彼伏,而不是交錯:) – codymanix 2011-06-06 15:52:59

+0

@codymanix:查看我的編輯方法。 – 2011-06-06 16:00:57

+0

你還需要一套。 – Tejs 2011-06-06 18:10:23

3

不,它是不是一個錯誤。它是通過語言的設計。

當你寫

var obj1 = new MyList() { Text="Hello" }; 

,這是有效的編譯器轉換爲

MyList temp = new MyList(); 
temp.Text = "Hello"; 
MyList obj = temp; 

當你寫

var obj2 = new MyList() { 1, 2, 3 }; 

,這是有效的編譯器轉換爲

MyList temp = new MyList(); 
temp.Add(1); 
temp.Add(2); 
temp.Add(3); 
MyList obj2 = temp; 

請注意,在第一種情況下,您使用的是對象初始值設定項,但在第二種情況下,您正在使用集合初始值設定項。沒有像對象和集合初始化器那樣的東西。您要麼初始化您的對象的屬性,要麼正在初始化該集合。你不能這樣做,這是設計。

此外,你不應該從List<T>派生。請參閱:Inheriting List<T> to implement collections a bad idea?

+0

我知道它是如何翻譯的。我仍然看不出爲什麼我們不能將第一個和後一個結合起來。 – codymanix 2011-06-06 15:22:56

+2

@codymanix:因爲它不在語言規範中。 – jason 2011-06-06 15:24:44

+0

我想知道爲什麼這是downvoted。 – jason 2011-06-06 15:46:45

2

如果你想要得到的東西像這樣的功能,考慮制定構造函數的參數:

var x = new CustomList("Hello World") { 1, 2, 3 } 
+1

但是在我有很多參數的情況下,但在大多數情況下只想設置它們中的幾個的情況下,這不會是最好的解決方案 – codymanix 2011-06-06 15:49:10