C#嵌套对象初始化程序

时间:2019-01-28 02:40:04

标签: 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();
        }
    }
}

我评论了根据规范应该在其中生成编译器错误的代码。但是它编译成功。我在这里想念什么?

谢谢

1 个答案:

答案 0 :(得分:5)

您拥有的不是嵌套对象初始化程序,因为您显式创建了MemberStruct的新实例。内部对象初始值设定项不直接跟等号,而是一个单独的对象初始值设定项,与对MemberStruct构造函数的调用关联。

这是使用嵌套对象初始化程序的样子:

ContainingClass cc = new ContainingClass { Field = 1, MS = { field1 = 1, field2 = 1.2} };

当MS是值类型(结构)时,不会编译,但是当MS是引用类型(对象)时,它将编译。