C# 值类型列表

C# Value Type Lists

我有点困惑。结构或多或少是在堆栈上构建的值类型,因此具有简单的生命周期。

使用结构体构建列表时,不能直接修改它们,因为返回值是一个副本,不会真正修改存储在列表中的项。

我的困惑来了:为什么我不能直接更改列表中的结构项,但我可以直接访问和修改基值类型(int、float 等...)?

这个有效:

 List<int> foobar1 = new List<int>();
 foobar1.Add(1);
 foobar1[0] = 2;

这不是:

public struct foo
{
    public int bar;
}

...         

List<foo> foobar2 = new List<foo>();
foobar2.Add(new foo());
foobar2[0].bar = 2;

两者根本不同,不只是因为有人认为它是不同的,让我解释一下。

第一段代码替换了列表中第 0 个元素位置的 int 值。哪个 int 值并不重要,之后列表在第 0 个位置包含 int2

然而,第二段代码试图替换结构的部分。是的,我知道,该结构只有一个字段,但编译器没有做出这样的区分。您实际上是在修改从列表中检索到的结构的副本。这是不允许的。

所以第一段代码只是将一个新的值类型塞入列表,第二段代码尝试修改列表中的值类型,这是一个副本。

所以,你能不能把第二段代码改成和第一段一样,即。完全替换列表中的元素?

当然可以:

var temp = foobar[0];
temp.bar = 2;
foobar2[0] = temp; // no longer modifies the copy, but replaces the element

基本上,就在这里:

foobar2[0].bar = 2;
          ^    ^
          |    |

是问题所在。