Reputation: 1342
I'm a bit confused. Structs are more or less value types that get constructed on the stack and therefore have a straightforward lifetime.
When building a list with a struct, you cannot modify them directly because the returned value is a copy, and won't actually modify the item stored in the list.
My confusion comes here: Why can I not directly change a struct item in a list, but I can directly access and modify the base value types (int, float, etc...)?
This works:
List<int> foobar1 = new List<int>();
foobar1.Add(1);
foobar1[0] = 2;
This Doesn't:
public struct foo
{
public int bar;
}
...
List<foo> foobar2 = new List<foo>();
foobar2.Add(new foo());
foobar2[0].bar = 2;
Upvotes: 2
Views: 2953
Reputation: 391326
The two are fundamentally different, and not just because someone decided that it is, let me explain.
The first piece of code replaces wholesale the int
value in the 0th element position in the list. It doesn't matter which int
value is there, afterwards the list contains the int
value 2
in the 0th position.
The second piece of code, however, is attempting to replace parts of the struct. Yes, I know, the struct only has one field but the compiler makes no such distinction. You're effectively modifying a copy of the struct retrieved from the list. This is not allowed.
So the first piece of code just stuffs a new value type into the list, the second piece of code tries to modify the value type from the list, which is a copy.
So, can you change the second piece of code to be like the first, ie. replace the element in the list completely?
Sure:
var temp = foobar[0];
temp.bar = 2;
foobar2[0] = temp; // no longer modifies the copy, but replaces the element
Basically, this right here:
foobar2[0].bar = 2;
^ ^
| |
is the problem.
Upvotes: 4