C# 3.0语言新特性(语言规范):4 对象和集合初始化器

对象|规范|集合

原文:《C# Version 3.0 Specification》,Microsoft
翻译:lover_P
一个对象创建表达式可以包含一个对象或集合初始化器,用于初始化新创建的对象的成员或新创建的集合的元素。

object-creation-expression:
new  type  (  argument-listopt  )  object-or-collection-initializeropt
new  type  object-or-collection-initializer

object-or-collection-initializer:
object-initializer
collection-initializer

一个对象创建表达式可以省略构造器参数列表,并将其连同圆括号一起替换为一个对象或集合初始化器。省略构造器参数列表并将其连同圆括号一起替换为一个对象或集合初始化器等价于指定一个空的参数列表。

在执行一个带有对象或集合初始化器的对象创建表达式时,首先调用实例构造器,然后执行对象或集合初始化器指定的成员或元素初始化。

对象或集合初始化器不能引用正在初始化的对象实例。

4.1 对象初始化器

对象初始化器指定了对象的一个或多个域或属性的值。

object-initializer:
{  member-initializer-listopt  }
{  member-initializer-list  ,  }

member-initializer-list:
member-initializer
member-initializer-list  ,  member-initializer

member-initializer:
identifier  =  initializer-value

initializer-value:
expression
object-or-collection-initializer

对象初始化器由一系列的成员初始化器构成,包围在{和}记号中,并用逗号进行分隔。每个成员初始化器以对象的一个可访问的域或属性的名字开始,后跟一个等号,之后是一个表达式或一个对象或集合初始化器。如果对象初始化其中包括了对同一个域或属性的多于一个的成员初始化器,将会发生错误。

在等号后面指定了表达式的成员初始化器的处理与域和属性的赋值一致。

在等号后面指定了对象初始化器的成员初始化器也是对一个嵌套对象的初始化。与为域或属性赋一个新值不同,对象初始化器中的赋值被视为对域或属性的成员进行赋值。一个具有值类型的属性不能通过这种构造来进行初始化。

在等号后面指定了集合初始化器的成员初始化器也是对一个嵌套集合的初始化。与为域或属性赋一个新的集合不同,初始化器中给定的元素将被添加到域或属性所引用的集合中。该域或属性必须是一个满足下一节所指定的需求的集合类型。

下面的类表是一个具有两个坐标值的点:

public class Point

{

    int x, y;

 

    public int X { get { return x; } set { x = value; } }

    public int Y { get { return y; } set { y = value; } }

}

Point的一个实例可以像下面这样创建和初始化:

var a = new Point { X = 0, Y = 1 };

其等价于:

var a = new Point();

a.X = 0;

a.Y = 1;

下面的类表是一个具有两个点的矩形:

public class Rectangle

{

    Point p1, p2;

 

    public Point P1 { get { return p1; } set { p1 = value; } }

    public Point P2 { get { return p2; } set { p2 = value; } }

}

可以像下面这样创建和初始化一个Rectangle:

var r = new Rectangle {

    P1 = new Point { X = 0, Y = 1 },

    P2 = new Point { X = 2, Y = 3 }

};

其等价于:

var r = new Rectangle();

var __p1 = new Point();

__p1.X = 0;

__p1.Y = 1;

r.P1 = __p1;

var __p2 = new Point();

__p2.X = 2;

__p2.Y = 3;

r.P2 = __p2;

其中的__p1和__p2是临时变量,在其他地方不可见也不可访问。

如果Rectangle的构造器分配了两个嵌套的Point实例:

public class Rectangle

{

    Point p1 = new Point();

    Point p2 = new Point();

 

    public Point P1 { get { return p1; } }

    public Point P2 { get { return p2; } }

}

下面的构造可以用来初始化内嵌的Point实例,而不是为其赋以新值:

var r = new Rectangle {

    P1 = { X = 0, Y = 1 },

    P2 = { X = 2, Y = 3 }

};

其等价于:

var r = new Rectangle();

r.P1.X = 0;

r.P1.Y = 1;

r.P2.X = 2;

r.P2.Y = 3;

4.2 集合初始化器

集合初始化器指定了集合的元素。

collection-initializer:
{  element-initializer-listopt  }
{  element-initializer-list  ,  }

element-initializer-list:
element-initializer
element-initializer-list  ,  element-initializer

element-initializer:
non-assignment-expression

一个集合初始化器由一系列的元素初始化器构成,包围在{和}记号之间,并使用逗号进行分隔。每个元素初始化器指定一个元素,该元素将被添加到待初始化的集合对象中。为了避免与成员初始化器混淆,元素初始化器不能是赋值表达式。

下面是包含了集合初始化器的对象创建表达式的一个例子:

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

可以应用集合初始化器的对象的类型必须实现了System.Collections.Generic.ICollections<T>并指定了确定的T。此外,必须存在从每个元素初始化器的类型到T的隐式转换。如果这些条件不能满足,就会产生一个编译期错误。集合初始化器将依次对每个指定的元素调用ICollection<T>.Add(T)。

下面的类表是一个具有一个名字和一组电话号码的通讯录:

public class Contact

{

    string name;

    List<string> phoneNumbers = new List<string>();

 

    public string Name { get { return name; } set { name = value; } }

    public List<string> PhoneNumbers { get { return phoneNumbers; } }

}

可以像下面这样创建和初始化一个List<Contact>:

var contacts = new List<Contact> {

    new Contact {

        Name = "Chris Smith",

        PhoneNumbers = { "206-555-0101", "425-882-8080" }

    },

    new Contact {

        Name = "Bob Harris",

        PhoneNumbers = { "650-555-0199" }

    }

};

其等价于:

var contacts = new List<Contact>();

var __c1 = new Contact();

__c1.Name = "Chris Smith";

__c1.PhoneNumbers.Add("206-555-0101");

__c1.PhoneNumbers.Add("425-882-8080");

contacts.Add(__c1);

var __c2 = new Contact();

__c2.Name = "Bob Harris";

__c2.PhoneNumbers.Add("650-555-0199");

contacts.Add(__c2);

其中__c1和__c2是临时变量,在其他地方不可见且不可访问。

 

时间: 2024-10-28 15:11:14

C# 3.0语言新特性(语言规范):4 对象和集合初始化器的相关文章

C#3.0语言新特性之对象和集合初始化器

在C#3.0中,一个对象创建表达式可以包含一个对象或集合初始化器,用于初 始化新创建的对象的成员或新创建的集合的元素. 对象创建表达式: new type (argument-list(可选)) 对象或集合初试化器(可选) new type 对象或集合初试化器 一个对象创建表达式可以省略构造器参数列表,并将其连同圆括号一起替换 为一个对象或集合初始化器.省略构造器参数列表并将其连同圆括号一起替换为 一个对象或集合初始化器等价于指定一个空的参数列表. 在执行一个带有对象或集合初始化器的对象创建表达

C# 3.0语言新特性(语言规范):1 具有隐式类型的局部变量

变量|规范 原文:<C# Version 3.0 Specification>,Microsoft翻译:lover_P 在一个具有隐式类型的局部变量声明(implicitly typed local variable declaration)中,被声明的局部变量的类型是通过初始化该变量的表达式推断出来的.当使用局部变量声指示符符var来代替类型,并且当前作用域内没有名为var的类型时,这个声明便成为一个具有隐式类型的局部变量声明.例如: var i = 5; var s = "Hel

AS代码2.0:新的语言元素

Flash的ActionScript(简称AS)代码控制是Flash实现交互性的重要组成部分,也是区别于其他动画软件的看家本领.今年新发布的Flash MX Professional 2004的动作脚本语言已经升级到2.0,它是一种面向对象的脚本语言,执行ECMA-262脚本语言规范,支持继承.强类型和事件模型.使用动作脚本语言2.0可以编写出更加稳健的脚本. 动作脚本语言2.0的新特性包括:新的语言元素.改进的编辑和调试工具.引入更多.的面向对象编程模型. 本系列文章将向大家详细介绍AS代码2

《Visual C++ 2012 开发权威指南》——第2章 Visual C++2012语言新特性2.1 Visual C++2012的语言新特性(1)

第2章 Visual C++2012语言新特性 Visual C++ 2012 开发权威指南 有一种新的C++标准就有一种新版本的Visual C++,新的版本Visual C++将更加符合C++标准!在其发展过程中新的C++标准被(乐观)称为C++0x.它最后被发布在2011年,现在称为C++11. 对于Visual C++,它有三个不同版本的数字,有不同的内部版本和编译器版本(cl.exe和_MSC_VER宏-显示不同,因为我们C++编译器早在Visual C++中的"可视化").

《Visual C++ 2012 开发权威指南》——2.2 Visual C++2012的语言新特性(2)

2.2 Visual C++2012的语言新特性(2) Rvalue引用:N1610"Rvalues类对象的初始化的澄清"是早期尝试启用无rvalue引用move 语意. 这些新规则还没有完全实现VC11开发者预览中. Rvalue引用v3.0添加自动生成的构造函数和移动赋值运算符在一定条件下的新规则.这不会进行中VC11,还将继续遵循的永远不会自动生成move构造函数/移动页本页的行为. 移动语义 Rvalue引用支持移动语义的实现,可以显著提高应用程序的性能.移动语义使能够调用资源

《Visual C++ 2012 开发权威指南》——2.3 Visual C++2012的语言新特性(3)

2.3 Visual C++2012的语言新特性(3) 在VC12(Visual C++2012),我们打算完全支持C++11标准库,但实施编译器功能可以自定义(另外,VC12不会完全实现C99标准库,已经通过引用纳入C++11标准库.注意本页和VC12已经有).这里是我们不断的变化的非详尽列表: 新头文件:......和. 进驻:根据需要由C++11,我们已经实现了emplace()/emplacefront()/emplace_back()/ emplace hint()/emplace_a

Spring 2.0的新特性点评

Spring2.0的发布恐怕算得上2006年Java社区的一件大事了.在Spring2.0发布附带的文档里面对2.0新特性做了概要的介绍,2.0的新特性是自然是我们最关注的方面: 一.Spring的XML配置引入XML Schema语法简化配置 在Spring1.x系列中,bean的配置文件使用DTD,没有namespace的分隔.2.0的一个非常大的改进是引入了XML Schema的namespace,因而可以将bean的配置文件做大幅度的简化.这些简化包括了对bean属性的各种简化,AOP配

《Ext JS实战》——1.4 Ext JS 3.0的新特性

1.4 Ext JS 3.0的新特性 Ext JS 2.0中引入的一些变化是颠覆性的,这就导致从级到2.0相当困难.这主要是因为这一版引入了一个更加现代的布局管理器以及一个崭新的.健壮的组件层次,许多Ext JS 1.x的代码都会因此而崩溃.值得庆幸的是,由于Ext JS 2.0的良好的工艺设计,从Ext JS 2.0到3.0的移植就非常容易了.尽管Ext JS 3.0新增的内容并不怎么神奇,不过最新的版本还是可圈可点的,有些新增的特性还是值得讨论的. 1.4.1 Ext JS通过Direct完

C#7.0中新特性汇总_C#教程

以下将是 C# 7.0 中所有计划的语言特性的描述.随着 Visual Studio "15" Preview 4 版本的发布,这些特性中的大部分将活跃起来.现在是时候来展示这些特性,你也告诉借此告诉我们你的想法! C#7.0 增加了许多新功能,并专注于数据消费,简化代码和性能的改善.或许最大的特性就是元祖和模式匹配,元祖可以很容易地拥有多个返回结果,而模型匹配可以根据数据的"形"的不同来简化代码.我们希望,将它们结合起来,从而使你的代码更加简洁高效,也可以使你更加