更改对象数组中的值

Changing value in array of objects

提问人:Kosmonik 提问时间:8/12/2022 更新时间:8/12/2022 访问量:678

问:

我有一点代码,我对我的观察感到困惑

var arr = new Class[]
{
    new Class{Name = "First"},
    new Class{Name = "Second"}
};

var first = arr[0];

arr[0] = new Class { Name = "Third"};

Console.WriteLine(first.Name); //Name = First

class Class
{
    public string Name { get; set; }
}

起初,我认为这段代码应该写“Third”,因为它是对对象的引用数组,我们正在将 arr[0] 更改为“Third”,但是在数组中更改引用后,第一个变量具有“First”值。

我假设,发生这种情况是因为当我们得到 arr[0] 时,我们通过值获得引用,就像如果我们将对象传递给某个函数,我们可以更改对象的状态,但我们不能更改整个对象。这就是为什么第一个变量继续指向名为“First”的对象。我试图用这段代码来证明这个假设

ref Class first = ref arr[0];

arr[0] = new Class { Name = "Third" };

Console.WriteLine(first.Name); //Name = Third

但我不确定。有人可以证明或反驳吗?

C# .NET 逐个 引用

评论


答:

1赞 lee-m 8/12/2022 #1

你的假设是正确的。该变量仍指向最初位于 的对象。更新只会只更新该数组元素,所指的内容保持不变。firstarr[0]arr[0]first

从 Dan Abramov 出色的 Just Javascript 系列中汲取灵感来解释变量和值,您可以构建一个将变量作为“电线”的心理模型,将变量与值联系起来。此处的值是对象引用。有了这个,你可以想象正在发生的事情:Class

  • 创建包含两个元素的数组。这会在内存中创建两个对象来存储某些内容(两个值,连线返回到每个数组元素变量)。
  • 您创建的变量具有 的导线。 并且现在引用相同的值(对象引用)。firstarr[0]firstarr[0]
  • 分配给新对象。这将创建一个值(对象引用),并将连接的导线从旧值移动到新值。arr[0]arr[0]
  • 来自的电线保持不变 - 它仍然连接到最初在 中的原始值。firstarr[0]

这个心智模型适用于参考类型,如果你的值是值类型,那么每次使用都会创建一个新值,并将导线从被分配的变量移动到该新值。多根电线连接到它不会有任何价值。new