对于此类设置。
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 提出的建议很奇怪。
我只是在寻找要查找的语言功能关键字或简单的解释。
最佳答案
语法是任意的,严格来说,但在我看来,考虑它的方式是 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 会反对您拿起武器对抗花括号的海洋。我更喜欢你的原版。
关于C# 初始化语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43723323/