C# 嵌套对象初始值设定项

C# nested object initializer

C# 5.0 语言规范 7.6.10.2 对象初始值设定项 指出

A member initializer that specifies an object initializer after the equals sign is a nested object initializer, i.e. an initialization of an embedded object. Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property. Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type.

虽然我知道在构造函数 运行 之后初始化程序不能修改只读字段,但我不知道对属性的限制。

以下是我用来测试此属性限制的代码示例:

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是值类型(struct)时不会编译,但当MS是引用类型(object)时会编译。