一、 引言
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新引入的特征之一,提供了一种新的语法来初始化集合对象。这种简单的语法把集合对象的创建和初始化结合到一个步骤中。 商业源码热门下载www.html.org.cn