Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List and Array of structs value vs variable

Tags:

arrays

c#

struct

I'm trying to understand/reconcile my understanding of how C# structs operate when chaining using List and Arrays. I follow Eric's explanation in this post Performance of array of struct types

but I'm taking this one step further.

struct Foo { public int A; public int B; public Foo[] ChildFoos; }

Foo parentFoo = new Foo();
parentFoo.ChildFoos = new Foo[1];
parentFoo.ChildFoos[0] = new Foo();

List<Foo> list = new List<Foo>();
list.Add(parentFoo);

But the behavior changes when you chain the calls. list[0] should be returning a value (not a variable) where as ChildFoos[0] should be returning a variable.

list[0].ChildFoos[0].A = 4545;

In this case what appears to be happening is list[0] is being treated as a variable instead of a value. ChildFoos[0].A maintains it's new value in the parentFoo within the List. How is this possible?

Compare this with attempting to set A on the parent Foo struct which won't compile.

list[0].A = 877;

This will not compile

like image 513
Bob Jones Avatar asked Oct 28 '22 22:10

Bob Jones


1 Answers

So, as you have correctly stated, list[0] is a copy of the value in the list. It's a value, and not a variable. One of the values in that struct is ChildFoos. The value of that field is not a whole bunch of Foo instances; instead it's a reference to a bunch of information stored elsewhere (because arrays are reference types). The copy of the Foo instance you're given back has a copy of the reference that the instance inside of the list has.

If you were to mutate the reference itself, say by assigning a new array to ChildFoos, you'd see the same error that you see when you try to mutate any other field of that struct, like when you try to mutate A. As it is you're only reading the value of the reference that the struct stores (and not mutating the struct instance), then going and getting the first item in that array, and since the array indexer return a variable, not a value (again, as you noted correctly in the question) mutating that returned Foo instance is mutating the instance in the array, as it's not a copy, so when you access that same array again, later, you'll be able to observe the change.

like image 78
Servy Avatar answered Nov 15 '22 05:11

Servy