C# 3.0 引入集合初始化器,讓實作 ICollection<T> 的型別能像陣列一樣以宣告式語法初始化。本文詳細說明語法規則、編譯器轉換、巢狀集合與 IL 層面驗證。
集合初始化器由大括號包裹的元素初始化器序列組成,以逗號分隔:
List<string> names = new List<string> { "Alice", "Bob", "Chris" };
限制條件:
System.Collections.Generic.ICollection<T>(單一 T)。T。X = 1),必須為物件建立運算式或值。Add 方法呼叫。可同時使用物件初始化器建構元素,並初始化元素內部的集合屬性:
public class MyClass
{
public string NameOfClass;
public List<string> StudentNames = new List<string>();
}
var classes = new List<MyClass>
{
new MyClass
{
NameOfClass = "Science",
StudentNames = { "Laura", "George" } // 集合屬性初始化
},
new MyClass
{
NameOfClass = "Commerce",
StudentNames = { "Bill", "Hillary" }
}
};
上述初始化器編譯器轉換為:
var classes = new List<MyClass>();
var __c1 = new MyClass();
__c1.NameOfClass = "Science";
__c1.StudentNames.Add("Laura");
__c1.StudentNames.Add("George");
classes.Add(__c1);
var __c2 = new MyClass();
__c2.NameOfClass = "Commerce";
__c2.StudentNames.Add("Bill");
__c2.StudentNames.Add("Hillary");
classes.Add(__c2);
使用 ILDASM 檢視編譯後的 Main 方法,可見:
newobj 建構元素、stfld 設定屬性、callvirt 呼叫 List<T>.Addstloc.0 指派給目標變數這證明集合初始化器純粹為編譯期語法糖,不引入執行期額外開銷。
select new List<T> { ... }AddRange、List<T>(capacity) 或資料流處理