日期:2010-09-22  浏览次数:20479 次

  一、 引言

  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<