2

在使用可变结构和属性时,编译器可以弄清楚一些事情,但对其他相当明显的事情却不能做同样的事情,这对我来说似乎很奇怪。

以下面的自动属性为例:

Vector2 Vector { get; set; }

而不是输入这个:

Vector2 v = Vector;
v += new Vector2(5, 7);
Vector = v;

编译器足够聪明,可以让我这样做:(结构的可变性在这里没有影响)

Vector += new Vector2(5, 7);

但似乎编译器不够聪明,无法让我执行以下操作,即使我可以同时访问 setter 和 getter -

Vector.X += 4;

相反,我被迫“手动”执行此操作-

Vector2 v = Vector;
v.X += 4;
Vector = v;

编译器团队决定允许第一种速记形式而不是第二种速记形式有什么特别的原因吗?
除了建议的方式显然更简洁之外,我还认为它可能允许更有效地内联 NGEN/JIT,因为很明显 getter 生成的副本不会在其他任何地方使用。(仅当这可以以某种方式反映在 IL 代码中时)

4

2 回答 2

2

如果Vector2是结构(值类型),则分配给将分配给属性someObject.Vector.X返回的临时副本。Vector这从来没有意义,因此是不允许的。

请参阅为什么可变结构是“邪恶的”?供一般参考和一些链接。

于 2012-08-07T20:48:55.817 回答
2

这不是编译器足够聪明的问题,而是代码编译成什么的问题。

Vector += new Vector2(5, 7);

编译为

Vector = Vector + new vector2(5,7);

所以我们有一个任务。一切都好。

Vector.X += 2;

编译为

var v = Vector;
v.X = v.X + 2

没有分配回Vector

于 2012-08-07T20:49:13.067 回答