c# - C# 嵌套对象初始化器
问题描述
C# 5.0 语言规范 7.6.10.2对象初始化器声明
在等号之后指定对象初始化器的成员初始化器是嵌套对象初始化器,即嵌入对象的初始化。嵌套对象初始值设定项中的赋值不是为字段或属性分配新值,而是被视为对字段或属性成员的赋值。嵌套对象初始值设定项不能应用于具有值类型 的属性或具有值类型的只读字段。
虽然我知道在构造函数运行后初始化程序无法修改只读字段,但我对属性的限制一无所知。
以下是我用来测试此属性限制的代码示例:
using System;
namespace ObjectCollectionInitializerExample
{
struct MemberStruct
{
public int field1;
public double field2;
}
class ContainingClass
{
int field;
MemberStruct ms;
public int Field
{
get { return field; }
set { field = value; }
}
public MemberStruct MS
{
get { return ms; }
set { ms = value; }
}
}
class Program
{
static void Main(string[] args)
{
// Nested object initializer applied to a property of value type compiles!
ContainingClass cc = new ContainingClass { Field = 1, MS = new MemberStruct { field1 = 1, field2 = 1.2} };
Console.ReadKey();
}
}
}
我评论了应该根据规范生成编译器错误的代码。但它编译成功。我在这里想念什么?
谢谢
解决方案
您拥有的不是嵌套对象初始化程序,因为您显式创建了 MemberStruct 的新实例。内部对象初始值设定项不直接跟在等号之后,而是一个自身的对象初始值设定项,与对 MemberStruct 构造函数的调用相关联。
这就是使用嵌套对象初始化器的样子:
ContainingClass cc = new ContainingClass { Field = 1, MS = { field1 = 1, field2 = 1.2} };
当 MS 是值类型(结构)时,这不会编译,但当 MS 是引用类型(对象)时,它会编译。