【问题标题】:New C# 6 object initializer syntax?新的 C# 6 对象初始化器语法?
【发布时间】:2015-10-01 22:12:51
【问题描述】:

我刚刚注意到在 Visual Studio 2015 中编写的 C# 中可以进行以下操作,但我以前从未见过:

public class X
{
    public int A { get; set; }

    public Y B { get; set; }
}

public class Y
{
    public int C {get; set; }
}

public void Foo()
{
    var x = new X { A = 1, B = { C = 3 } };
}

我的期望是 Foo 必须像这样实现:

public void Foo()
{
    var x = new X { A = 1, B = new Y { C = 3 } };
}

请注意,无需致电new Y

这是 C# 6 中的新功能吗?我在release notes 中没有看到任何提及,所以也许它一直都在那里?

【问题讨论】:

标签: c# roslyn c#-6.0


【解决方案1】:

如果您运行此代码,您将收到 NullReferenceException。

它不会创建Y的实例,它会调用X.B属性的getter并尝试为属性C赋值。

它总是这样工作。根据 C# 5.0 语言规范:

在等号之后指定对象初始化器的成员初始化器是嵌套对象初始化器,即嵌入对象的初始化。嵌套对象初始化程序中的赋值不是为字段或属性分配新值,而是被视为对字段或属性成员的赋值。

【讨论】:

  • 你是对的,谢谢。因此,我们可以将X.B 的声明更改为类似于public Y B { get; } = new Y();,并且此代码将按预期工作。奇怪的是我以前从未注意到这种语法!
  • 此功能是在 C# 3.0 中引入的
【解决方案2】:

这个特性是在 C# 3.0 中作为对象初始化器引入的。

请参见第 4 页上的示例。 C# Language 3.0 specification 中的 169 个:

Rectangle r = new Rectangle {
    P1 = { X = 0, Y = 1 },
    P2 = { X = 2, Y = 3 }
};

效果和

一样
Rectangle __r = new Rectangle();
__r.P1.X = 0;
__r.P1.Y = 1;
__r.P2.X = 2;
__r.P2.Y = 3;
Rectangle r = __r;

【讨论】:

    猜你喜欢
    • 2014-06-21
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 2013-06-27
    • 2018-12-24
    • 2015-12-03
    相关资源
    最近更新 更多