我试图理解/调和我对使用List和Arrays进行链接时C#结构如何运作的理解。我在这篇文章中跟随埃里克的解释 Performance of array of struct types
但是我更进一步。
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);
但是当您将呼叫链接起来时,行为会发生变化。 list [0]应该返回一个值(不是变量),其中ChildFoos [0]应该返回一个变量。
list[0].ChildFoos[0].A = 4545;
在这种情况下,似乎正在发生的事情是list [0]被视为变量而不是值。 ChildFoos [0] .A在List中的parentFoo中维护它的新值。这怎么可能?
将此与尝试在不会编译的父Foo结构上设置A进行比较。
list[0].A = 877;
这不会编译
答案 0 :(得分:2)
因此,正如您所说的那样,list[0]
是列表中值的副本。它是一个值,而不是一个变量。 struct
中的一个值是ChildFoos
。该字段的值不是一大堆Foo实例;相反,它是对存储在别处的一堆信息的引用(因为数组是引用类型)。您给出的Foo
实例的副本具有列表中实例所具有的引用的副本。
如果您要改变引用本身,比如通过为ChildFoos
分配一个新数组,您会看到当您尝试改变任何其他字段时看到的相同错误该结构的结构,就像你试图改变A
时一样。因为它只是读取结构存储的引用的值(而不是改变结构实例),然后去获取该数组中的第一项,并且因为数组索引器返回变量,而不是值(再次,正如您在问题中正确指出的那样)变异返回的Foo
实例正在改变数组中的实例,因为它不是副本,因此当您再次访问同一个数组时,稍后,你将能够观察到这种变化。