【问题标题】:C# Initializer SyntaxC# 初始化器语法
【发布时间】:2017-05-02 02:37:17
【问题描述】:

对于此类设置。

public class X
{
    public Y YInstance;

    public X()
    {
        YInstance = new Y();
    }
}

public class Y
{
    public long Z;
}

我有这个代码。

var x = new X();
x.YInstance.Z = 1;

Resharper 提示使用对象初始化器,它将我的代码转换为此。

var x = new X { YInstance = { Z = 1 } };

我熟悉使用方括号填写属性的普通对象初始化,但我不确定这是做什么的。查看 IL,它似乎没有使用新的匿名类设置 YInstance,这是我的第一个猜测。这也不会是与以前相同的功能,这对于 Resharper 的建议来说会很奇怪。

我只是在寻找一个语言特征关键字来查找或一个简单的解释。

【问题讨论】:

  • "IDE0017 C# 对象初始化可以简化"
  • R# 已经为您提供了要查找的关键词:“object initializer”。
  • 我只想指出,对象初始化器上的 msdn 没有提到在不创建新对象的情况下使用表单。 msdn.microsoft.com/en-us/library/bb384062.aspx

标签: c#


【解决方案1】:

语法是任意的,严格来说,但在我看来,考虑它的方式是YInstance = { Z = 1 } 没有new 关键字,所以它没有调用任何构造函数。然而,语法的初始化部分是存在的,所以它只是将初始化应用于(希望!)现有YInstance 的属性。 YInstance 存在于您的案例中,因为您在 X 构造函数中创建了它。 Here's what would happen if you didn't

不是“将 YInstance 设置为这个东西”,而是“将 YInstance 的 属性 设置为 那些 东西”。

= { ... } 在这种情况下意味着将该初始化程序应用于属性的现有值。

在属性名称和初始化大括号之间使用= 表示一开始可能看起来不太直观,但它就是这样,就像任何语法一样,你很快就会学会识别它。您可以执行相同的操作来初始化已创建的集合项:

public class C {
    public List<int> Items { get; } = new List<int>();
}

...

//  This can't be assigning to Items, because it's read-only
var c = new C { Items = { 0, 1, 2 } };

C# 团队成员之一(如果你提到他的名字,他会出现)once kindly took the time to comment on an answer to a question about the list initializer syntax。他们踢了很多次,但这是他们想出的最佳选择。在向成熟语言添加语法时,有很多考虑因素。他们为了让程序员尽可能清晰而失去了很多睡眠,但同时它必须对编译器明确,不能破坏现有代码等。“语法是任意的”并不意味着C# 团队做出任意决定。

我不能说为什么 Resharper 会反对你在花括号的海洋中拿起武器。我更喜欢你的原版。

【讨论】:

  • 感谢您为我打破了这一点!我的主要问题是我不知道您可以将 {...} 应用于已经创建的内容。我猜我只是将它用于初始创建。
  • @JakePadgett 这很奇怪,你看的不多,但是apparently it's been around for a while。如果你去项目属性 |构建 |高级...,它适用于 C#3.0,但不适用于 ISO-1 或 ISO-2。所以它的存在时间与var 一样长。但我找不到任何关于它的文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 2011-03-10
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多