当使用可变结构和属性时,我觉得奇怪的是编译器可以弄清楚一些事情,但不能对其他相当明显的事情做同样的事情。
以下面的自动属性为例:
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 代码中时)
如果
Vector2
是一个结构体(值类型),则分配给 someObject.Vector.X
将分配给 Vector
属性返回的临时副本。这毫无意义,因此是不允许的。
请参阅为什么可变结构是“邪恶的”?作为一般参考和一些链接。
这不是编译器是否足够聪明的问题,而是代码编译成什么的问题。
Vector += new Vector2(5, 7);
编译为
Vector = Vector + new vector2(5,7);
所以我们有一个任务。 一切都好。
Vector.X += 2;
编译为
var v = Vector;
v.X = v.X + 2
没有作业返回
Vector
。