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

Yeo*_*nho 12 c# linq foreach

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
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*ram 19

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

为了清楚起见,这里的查询定义是对于数字中的元素,创建一个新的Person并将当前数字元素的值赋给Person的Name属性.当您在foreach循环中进行迭代时,查询将进行求值,并创建新的Person对象.但那些Person对象不在查询中,它只是一个定义!再次运行查询会再次执行定义,从而创建不同的 Person对象.您修改查询的原始结果这一事实不会影响第二组结果.

如果您想立即执行,请使用

var people = numbers.Select(n => new Person() 
    { 
        Name = n.ToString() 
    }).ToList(); 
Run Code Online (Sandbox Code Playgroud)

你会在循环中发现你的变化,因为现在people是一个具体的列表而不是查询定义.

foreach (var person in people) 
{ 
     person.Name = newName; 
} 

Debug.WriteLine(people.First().Name.Equals(newName)); // returns true
Run Code Online (Sandbox Code Playgroud)


Les*_*ter 6

这是延迟执行的完美示例.

如果您尝试此示例,它将按预期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;
Run Code Online (Sandbox Code Playgroud)