【问题标题】:Why can't I set properties of iteration variables in a foreach loop?为什么我不能在 foreach 循环中设置迭代变量的属性?
【发布时间】:2012-02-25 17:40:01
【问题描述】:
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 循环中设置迭代变量的属性?

【问题讨论】:

  • 这不是一个有效的副本,这与分配给循环变量无关。这是延迟执行的问题。
  • @M.Babcock 我不认为这是一个重复的问题。链接中的问题试图分配给迭代变量本身,而我的问题分配给迭代变量的属性。不过谢谢!
  • @M.Babcock,这不是那个问题的重复。这个问题是关于修改迭代器本身的,因为迭代器是不可变的,所以无法做到这一点。然而,没有什么能阻止修改迭代器的内容(参见stackoverflow.com/a/776780/495041)。这种行为的原因是变量 people 是 IQuerable ,它在 foreach 循环运行时执行一次,在调用 First() 时再次执行,如 stackoverflow.com/a/9123015/495041 中所述

标签: c# linq foreach


【解决方案1】:

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

明确一点,这里的查询定义是对于numbers中的元素,新建一个Person,并将当前number元素的值赋给Person的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

【讨论】:

    【解决方案2】:

    这是deferred execution的完美示例。

    如果您尝试此示例,它会按预期工作,因为 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;
    

    【讨论】:

      猜你喜欢
      • 2012-03-30
      • 2012-06-29
      • 2015-03-09
      • 2019-04-12
      • 2017-01-15
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多