Here's the thing.
You say this:
I want to leave the structure for Foo.
How should I proceed? foos[0] =
tempFoo? little bit complicated just
for an assignment?!.
Yeah, well, that's just it. What you need is an assignment, not a modification. Value types (structs) are generally supposed to be treated as values.
Take int
. If you had a List<int>
called ints
, how would you change the value at ints[0]
?
Something like this, right?
ints[0] = 5; // assignment
Notice there's no way to do something like this:
ints[0].ChangeTo(5); // modification?
That's because Int32
is an immutable struct. It is intended to be treated as a value, which cannot be changed (so an int
variable can only be assigned to something new).
Your Foo
struct is a confusing case because it can be mutated. But since it's a value type, only copies are passed around (same as with int
, double
, DateTime
, etc. -- all the value types we deal with on a regular basis). For this reason you cannot mutate an instance "from afar"--that is, unless it is passed to you by ref (using the ref
keyword in a method call).
So the simple answer is, yeah, to change a Foo
in a List<Foo>
, you need to assign it to something new. But you really shouldn't have a mutable struct to begin with.
Disclaimer: As with almost any advice you can receive, in anything, this is not a 100% hard rule. The very skilled developer Rico Mariani wrote the Point3d
struct to be mutable for good reasons, which he explained on his blog. But this is a case of a very knowledgeable developer knowing exactly what he's doing; in general, as a standard approach to writing value types versus reference types, value types should be made immutable.
In response to your comment: so when you are dealing with a mutable struct like Point
, basically you need to do something like this:
Point p = points[0];
p.Offset(0, 5);
points[0] = p;
Or, alternatively:
Point p = points[0];
points[0] = new Point(p.X, p.Y + 5);
The reason I wouldn't do...
points[0] = new Point(points[0].X, points[0].Y + 5);
...is that here you're copying the value at points[0]
twice. Remember that accessing the this
property by index is basically a method call. So that code is really doing this:
points.set_Item(0, new Point(points.get_Item(0).X, points.get_Item(0).Y + 5);
Note the excessive call to get_Item
(making an additional copy for no good reason).