为什么我不能在 foreach 循环中设置迭代变量的属性

本文关键字:迭代 设置 变量 属性 循环 不能 foreach 为什么 | 更新日期: 2023-09-27 18:22:14

string newName = "new name";
int[] numbers = new int[] { 1, 2, 3 };
var people = numbers.Select(n => new Person()
{
    Name = n.ToString()
});
foreach (var person in people)
{
    person.Name = newName;
}
Debug.WriteLine(people.First().Name == newName); // returns false

我希望上面的行返回 true。为什么我不能在 foreach 循环中设置迭代变量的属性?

为什么我不能在 foreach 循环中设置迭代变量的属性

people是具有延迟执行的查询定义。您对查询的 foreach 无关紧要,这与无法设置属性无关。调用 First(),再次运行查询。

需要明确的是,此处的查询定义是,对于数字中的元素,创建一个新的 Person 并将当前数字元素的值分配给 Person's Name 属性。在 foreach 循环中循环访问时,查询将计算,并创建新的 Person 对象。但是这些 Person 对象不在查询中,它只是一个定义!再次运行查询将再次执行定义,从而创建不同的 Person 对象。您修改了查询的原始结果这一事实不会影响第二组结果。

如果您希望立即执行,请使用

var people = numbers.Select(n => new Person() 
    { 
        Name = n.ToString() 
    }).ToList(); 

你会发现你在循环中的更改是粘性的,因为现在people是一个具体的列表,而不是一个查询定义。

foreach (var person in people) 
{ 
     person.Name = newName; 
} 
Debug.WriteLine(people.First().Name.Equals(newName)); // returns true

这是延迟执行的一个完美示例。

如果您尝试此示例,它将按预期工作,因为ToList执行查询。

    string newName = "new name";
    int[] numbers = new int[] { 1, 2, 3 };
    var people = numbers.Select(n => new Person()
    {
        Name = n.ToString()
    }).ToList(); // <===== here
    foreach (var person in people)
    {
        person.Name = newName;
    }
    var b = people.First().Name == newName;