Chaining properties in C# & unexpected results

2019-07-19 08:48发布

问题:

I was just having a quick read through this article (specifically the bit about why he chose to use structs / fields instead of classes / properties) and saw this line:

The result of a property is not a true l-value so we cannot do something like Vertex.Normal.dx = 0. The chaining of properties gives very unexpected results.

What sort of unexpected results is he talking about?

回答1:

I would add to dbemerlin's answer that the key here is Rico's note that properties are not "lvalues", or, as we call them in C#, "variables".

In order to mutate a mutable struct (and ideally, you should not; mutable structs often cause more problems than they solve) you need to mutate a variable. That's what a variable is -- a storage location whose contents change. If you have a field of type vector and you say

Foo.vector.x = 123;

then we have a variable of value type -- the field Foo.vector -- and we can therefore mutate its property x. But if you have a property of value type:

Foo.Vector.x = 123;

the property is not a variable. This is equivalent to

Vector v = Foo.Vector;
v.x = 123;

which mutates the temporary variable v, not whatever storage location is backing the property.

The whole problem goes away if you abandon mutable value types. To change x, make a new vector with the new values and replace the whole thing:

Foo.Vector = new Vector(x, Foo.Vector.y);


回答2:

The only "unexpected" result would be that the assignment wouldn't last because Vertex.Normal returns a copy and the code assigns 0 to dx of the copy.

I can't test it now but that is what i would expect (from what i know of .NETs handling of structs)