为什么通用列表索引器会出现两种行为?

问题描述 投票:2回答:2
static void Main(string[] args)
{
   var vs = new List<Person> { new Person(1) };
   vs[0].IncrementAge();

   Console.WriteLine(vs[0].Age);  // output: 1
}

struct Person
{
   public int Age { get; set; }

   public Person(int age) : this()
   {
      Age = age;
   }

   public int IncrementAge()
   {
      Age++;
      return Age;
   }
}

我明白为什么会得到这样的结果。列表索引器返回的是元素的副本。这是好的。

我的问题是,为什么我们在下面的代码中没有得到同样的结果? 因为我改变了一个元素副本的值。

static void Main(string[] args)
{

   var vs = new List<int> { 1 };
   vs[0] = 2;

   Console.WriteLine(vs[0]);     // output: 2, **why not 1?**
}

为什么覆盖整个元素副本的值会影响列表?我想知道这段代码在后台是如何工作的。

c# generics struct indexer
2个回答
3
投票

在这一行中。

vs[0].IncrementAge();

在这一行中: 你 检索 指数0的值,这将创建一个 拷贝struct. 在副本中, Age 得到递增,而副本是 遂失. 它不会被保存回列表中。

在这种情况下: vs[0] 被翻译为调用一个返回值的getter方法。这就和(伪代码)一样了。

vs.get_Item(0).IncrementAge();

恰恰相反,在这里,

vs[0] = 2;

替换 0位置的值换成新的。这就是为什么它改变了 列表中.

在这方面: vs[0] 翻译为调用一个setter方法,将提供的值存储到列表的内部数据结构中。这将和(伪代码)一样。

vs.set_Item(0, 2);

0
投票

数组索引器返回一个对数组元素的引用 数组的值会被改变 但列表的值不会被改变 列表索引器返回的是元素的副本。成员函数是在这个临时对象上调用的。所以,原来的列表成员根本不会改变。

© www.soinside.com 2019 - 2024. All rights reserved.