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?**
}
为什么覆盖整个元素副本的值会影响列表?我想知道这段代码在后台是如何工作的。
在这一行中。
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);
数组索引器返回一个对数组元素的引用 数组的值会被改变 但列表的值不会被改变 列表索引器返回的是元素的副本。成员函数是在这个临时对象上调用的。所以,原来的列表成员根本不会改变。