C# 3.0新特征之创建和初始化集合对象

简介:
一、 引言

  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类似的内容。 

C#3.0新特征之创建和初始化集合对象(2)
图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新引入的特征之一,提供了一种新的语法来初始化集合对象。这种简单的语法把集合对象的创建和初始化结合到一个步骤中。

















本文转自朱先忠老师51CTO博客,原文链接: http://blog.51cto.com/zhuxianzhong/59338,如需转载请自行联系原作者



相关文章
|
1月前
|
Java 物联网 C#
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
|
3月前
|
存储 C# 索引
C# 一分钟浅谈:数组与集合类的基本操作
【9月更文挑战第1天】本文详细介绍了C#中数组和集合类的基本操作,包括创建、访问、遍历及常见问题的解决方法。数组适用于固定长度的数据存储,而集合类如`List<T>`则提供了动态扩展的能力。文章通过示例代码展示了如何处理索引越界、数组长度不可变及集合容量不足等问题,并提供了解决方案。掌握这些基础知识可使程序更加高效和清晰。
86 2
|
2月前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
125 65
|
1月前
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
|
2月前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
|
3月前
|
SQL 开发框架 安全
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue&lt;T&gt;`和`ConcurrentDictionary&lt;TKey, TValue&gt;`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
56 1
|
3月前
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
29 2
|
4月前
|
存储 C# 索引
C# 集合语法全解
C# 集合语法全解
35 0
|
7月前
|
C#
C#的类和对象的概念学习案例刨析
【5月更文挑战第17天】C#是一种面向对象的语言,以类和对象为核心。类作为对象的模板,定义了属性(如Name, Age)和行为(如Greet)。对象是类的实例,可设置属性值。封装通过访问修饰符隐藏实现细节,如Customer类的私有name字段通过Name属性访问。继承允许新类(如Employee)从现有类(Person)继承并扩展。多态让不同对象(如Circle, Square)共享相同接口(Shape),实现抽象方法Area,提供灵活的代码设计。
71 1