【问题标题】:List and Array of structs value vs variable结构值与变量的列表和数组
【发布时间】:2018-05-22 00:38:29
【问题描述】:

我试图理解/调和我对 C# 结构在使用列表和数组进行链接时如何操作的理解。我在这篇文章中遵循 Eric 的解释 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 在列表中的 parentFoo 中维护它的新值。这怎么可能?

将此与尝试在无法编译的父 Foo 结构上设置 A 进行比较。

list[0].A = 877;

这不会编译

【问题讨论】:

  • 很好的问题和minimal reproducible example 的极好例子。操作。如果有人想尝试,这里是Fiddle
  • @himbrombeere 问题是问为什么变化可观察的,而不是为什么他们不能改变列表中结构的值。

标签: c# arrays struct


【解决方案1】:

因此,正如您正确指出的那样,list[0] 是列表中值的副本。它是一个值,而不是一个变量。 struct 中的值之一是ChildFoos。该字段的值不是一大堆 Foo 实例;相反,它是对存储在其他地方的一堆信息的引用(因为数组是引用类型)。您返回的Foo 实例的副本具有列表内实例所具有的引用的副本

如果您要改变引用本身,例如通过将新数组分配给ChildFoos,您会看到与尝试改变该引用的任何其他字段时看到的相同的错误struct,就像当你尝试改变 A 时一样。因为你只是读取结构存储的引用的值(而不是改变结构实例),然后去获取该数组中的第一项,并且由于数组索引器返回一个变量,而不是一个值(再次,正如您在问题中正确指出的那样),返回 Foo 实例的变异正在改变数组中的实例,因为它不是副本,所以当您再次访问同一个数组时,稍后,您'将能够观察到变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多