一、引言
C# 3.0中新的對象初始化器是一種簡單的語法特征-借助於 這種特征,對象的構建和初始化變得非常簡單。假定你有一個類Student,它看 起來有如下樣子:
public class Student{
public string firstName;
public string lastName;
}
那麼,你可以使用對象初始化器來創建這個類的一個對象,如下所示:
var student1 = new Student{firstName = "Bruce", lastName = "Willis"};
C# 3.0中新的集合初始化器 語法也具有類似操作特征。例如,實現 System.Collections.Generic.ICollection<T>的任何對象都可以使用一個集 合初始化器來初始化它的值。
一個集合初始化器由下列部分組成:
· 一個對象初始化器序列,用"{"和"}"符 號包括,並且由逗號隔開。
· 元素初始化器,它們中每一個都指 定一個元素以被添加到指定的集合對象中(元素初始化器不能是一個集合初始化 器中的賦值表達式)。
那麼,究竟它是如何工作的呢?一個集合初始化 器必須遵循下列規則:
· 應用集合初始化器的每一個集合對象必 須是一種實現了System.Collections.Generic.ICollection<T>的類型(恰好 針對一個T)。
· 必須存在從每一個元素初始化器到T類型的一種 隱式轉換。一個集合初始化器針對每一個指定的元素都會按序調用ICollection <T>.Add(T)方法。
作為一個例子,下面的集合初始化器創建並初始化 一個新的字符串集合-這個集合具有3個成員: "Alice","Bob"和"Chris",參考如下:
List<string> names = new List<string> { "Alice", "Bob", "Chris" };
注意:所有的初始值都是字符串類型。否則,你將得到一個編譯器錯誤。
二、實現集合初始化
假定你想描述一個班及其中的注冊同學。為 此,你可以通過使用C# 3.0中的集合初始化器編程實現,如下所示:
using System;
using System.Collections.Generic;
using System.Text;
using System.Query;
using System.Xml.XLinq;
using System.Data.DLinq;
namespace CollectionInitializer
{
class Program
{
public class MyClass
{
public string nameofClass;
public List<string> studentNames = new List <string>();
}
static void Main(string[] args)
{
var classes = new List<MyClass>
{
new MyClass
{
nameofClass = "Science",
studentNames = {"Laura", "George"}
},
new MyClass
{
nameofClass = "Commerce",
studentNames = {"Bill", "Hillary"}
}
};
}
}
}
如果你有Visual Studio 2005並且安裝了LINQ Preview,那麼可以在IDE中編譯上面的代碼。
如果你沒有VS 2005但是安裝了LINQ Preview,那麼你可以使用下列命令 來從命令行編譯該代碼:
C:\Program Files\LINQ Preview\Bin\Csc.exe
/reference:"C:\Program Files\LINQ Preview\Bin\System.Data.DLinq.dll"
/reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 \System.Data.dll
/reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 \System.dll
/reference:"C:\Program Files\LINQ Preview\Bin\System.Query.dll"
/reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 \System.Xml.dll
/reference:"C:\Program Files\LINQ Preview\Bin\System.Xml.XLinq.dll" Program.cs
三、代 碼剖析
讓我們更細致地分析一下前面的C# 3.0代碼:
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並且打開了編譯的二進制代碼形式,那 麼你能夠看到如圖1類似的內容。
圖1.示例代碼片斷的編譯的二進制形式
如果你雙擊在ILDASM中的Main結點,那麼你會看到下列代碼:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
//代碼大小 138 (0x8a)
.maxstack 3
.locals init ([0] class [mscorlib] System.Collections.Generic.List`1
<class CollectionInitializer.Program/MyClass>
classes,
[1] class [mscorlib]System.Collections.Generic.List`1
<class CollectionInitializer.Program/MyClass>
'<tampa> f__0',
[2] class CollectionInitializer.Program/MyClass
'<tampa>f__1',
[3] class CollectionInitializer.Program/MyClass
'<tampa>f__2')
IL_0000: nop
IL_0001: nop
IL_0002: newobj instance void class [mscorlib]System.Collections.
Generic.List`1<class CollectionInitializer.
Program/MyClass >::.ctor()
IL_0007: stloc.1
IL_0008: ldloc.1
IL_0009: nop
IL_000a: newobj instance void CollectionInitializer.
Program/MyClass::.ctor()
IL_000f: stloc.2
IL_0010: ldloc.2
IL_0011: ldstr "Science"
IL_0016: stfld string CollectionInitializer.
Program/MyClass::nameofClass
IL_001b: nop
IL_001c: ldloc.2
IL_001d: ldfld class [mscorlib]System.Collections.Generic.List`1
<string> CollectionInitializer.
Program/MyClass::studentNames
IL_0022: ldstr "Laura"
IL_0027: callvirt instance void class [mscorlib]System.
Collections.Generic.List`1<string >::Add(!0)
IL_002c: nop
IL_002d: ldloc.2
IL_002e: ldfld class [mscorlib]System.Collections.Generic.List`1
<string> CollectionInitializer.
Program/MyClass::studentNames
IL_0033: ldstr "George"
IL_0038: callvirt instance void class [mscorlib]System.Collections.
Generic.List`1<string>::Add(! 0)
IL_003d: nop
IL_003e: nop
IL_003f: ldloc.2
IL_0040: nop
IL_0041: callvirt instance void class [mscorlib]System.Collections.
Generic.List`1<class CollectionInitializer.
Program/MyClass>::Add(!0)
IL_0046: nop
IL_0047: ldloc.1
IL_0048: nop
IL_0049: newobj instance void CollectionInitializer.
Program/MyClass::.ctor()
IL_004e: stloc.3
IL_004f: ldloc.3
IL_0050: ldstr "Commerce"
IL_0055: stfld string CollectionInitializer.
Program/MyClass::nameofClass
IL_005a: nop
IL_005b: ldloc.3
IL_005c: ldfld class [mscorlib] System.Collections.Generic.List`1
<string> CollectionInitializer.
Program/MyClass::studentNames
IL_0061: ldstr "Bill"
IL_0066: callvirt instance void class [mscorlib]System.Collections.
Generic.List`1<string >::Add(!0)
IL_006b: nop
IL_006c: ldloc.3
IL_006d: ldfld class [mscorlib]System.Collections.Generic.List`1
<string> CollectionInitializer.
Program/MyClass::studentNames
IL_0072: ldstr "Hillary"
IL_0077: callvirt instance void class [mscorlib]System.Collections.
Generic.List`1<string>::Add(! 0)
IL_007c: nop
IL_007d: nop
IL_007e: ldloc.3
IL_007f: nop
IL_0080: callvirt instance void class [mscorlib]System.Collections.
Generic.List`1<class CollectionInitializer.
Program/MyClass>::Add(!0)
IL_0085: nop
IL_0086: ldloc.1
IL_0087: nop
IL_0088: stloc.0
IL_0089: ret
} //Program::Main方法結束
四、小結
從前面的一些代碼片斷中你可以看到,C# 3.0 在語法方面邁出了很大的一步。
集合初始化器,作為C# 3.0新引入的特 征之一,提供了一種新的語法來初始化集合對象。這種簡單的語法把集合對象的 創建和初始化結合到一個步驟中。