【问题标题】:What is happening with this C# object initializer code?这个 C# 对象初始化程序代码发生了什么?
【发布时间】:2018-10-24 20:02:27
【问题描述】:

这段 C# 代码是怎么回事?我什至不确定它为什么会编译。具体来说,它设置 Class1Prop 尝试使用对象初始化器语法的地方发生了什么?这似乎是无效的语法,但它会在运行时编译并产生空引用错误。

void Main()
{    
    var foo = new Class1
    {
        Class1Prop = 
        {
            Class2Prop = "one"
        }
    };
}

public class Class1
{
    public Class2 Class1Prop { get; set; }
}

public class Class2
{
    public string Class2Prop { get; set; }
}

【问题讨论】:

  • 我的猜测是这与类型推断有关......但我无法支持,所以我只是焦急地等待答案:)
  • 它编译是因为它是有效的语法。只有第一个对象初始值设定项需要遵循 new,但嵌套的不需要。如果您在构造函数中初始化Class1Prop(在Class1 中),它将正常工作。 Class2Prop = "one" 所做的只是设置属性的值。
  • 你能解释为什么你认为它不应该编译,为什么你认为这个有效的语法是无效的?规范或文档的哪一行让您相信这是无效的?这条线应该是固定的,因为它显然具有误导性。

标签: c#


【解决方案1】:

object initializer syntax 在 C# 规范中允许这样做,在该规范中称为 嵌套对象初始化器。相当于:

var _foo = new Class1();
_foo.Class1Prop.Class2Prop = "one"
var foo = _foo;

为什么会抛出空引用异常应该更清楚一点。 Class1Prop 从未在 Class1 的构造函数中初始化。

这种语法的好处是调用者可以使用方便的对象初始化语法,即使属性是 getter-only 来设置嵌套对象的可变属性。例如,如果 Class1Prop 是仅 getter 属性,则该示例仍然有效。

请注意,创建了一个不可访问的临时变量以防止在完全初始化运行之前访问字段或数组槽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2015-01-21
    • 2018-11-12
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 2020-12-13
    相关资源
    最近更新 更多