当使用可变结构和属性时,我觉得编译器可以解决一些问题似乎很奇怪,但对于其他相当明显的事情却不能这样做。
以下面的自动属性为例:
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代码中)
答案 0 :(得分:2)
如果Vector2
是结构(值类型),则分配给someObject.Vector.X
将分配给Vector
属性返回的临时副本。这从来没有意义,因此是不允许的。
请参阅Why are mutable structs “evil”?以获取一般参考和一些链接。
答案 1 :(得分:2)
这不是编译器足够智能的问题,而是代码编译的问题。
Vector += new Vector2(5, 7);
编译到
Vector = Vector + new vector2(5,7);
所以我们有一项任务。一切都很好。
Vector.X += 2;
编译到
var v = Vector;
v.X = v.X + 2
不能转回Vector
。