C#嵌套对象初始化器

Joh*_*ith 5 c# object-initializers

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我评论了应该根据规范生成编译器错误的代码.但它成功编译.我在这里错过了什么?

谢谢

Nin*_*rry 5

您拥有的不是嵌套对象初始值设定项,因为您显式创建了MemberStruct的新实例.内部对象初始值设定项不直接遵循等号,而是与对MemberStruct构造函数的调用相关联的对象初始值设定项.

这是使用嵌套对象初始化程序的方式:

ContainingClass cc = new ContainingClass { Field = 1, MS = { field1 = 1, field2 = 1.2} };
Run Code Online (Sandbox Code Playgroud)

当MS是值类型(struct)时,这不会编译,但是当MS是引用类型(对象)时它将编译.