rom*_*n m 3 c# ienumerable foreach c#-4.0
为什么我必须创建一个具体的实现,IEnumerable<T>以便在foreach循环中修改其成员?
这篇博文(图1)解释了这种行为,但我无法完全理解它.
我在这里有一个非常简单的代码片段来重现这个问题(C#4.0/.NET 4.0).
class Person
{
public int Age { get; set; }
public Person()
{
}
}
class Program
{
static void Main(string[] args)
{
//calling .ToList() on GetPeople() below will fix the issue
var people = GetPeople();
foreach (var item in people)
{
item.Age = DateTime.Now.Second;
}
foreach (var item in people)
{
Console.WriteLine("Age is {0}", item.Age);
}
Console.Read();
}
public static IEnumerable<Person> GetPeople()
{
int i = 0;
while (i < 3)
{
i++;
yield return new Person();
}
}
}
Run Code Online (Sandbox Code Playgroud)
每次迭代时people,它都会GetPeople()再次执行代码- 创建新的实例Person.中的代码GetPeople并没有当你调用运行GetPeople(); 它只在你打电话时开始运行:
var iterator = people.GetEnumerator();
iterator.MoveNext();
Run Code Online (Sandbox Code Playgroud)
......这就是foreach循环所做的.
如果调用ToList(),则意味着您只需执行GetPeople() 一次代码,并存储迭代序列时返回的引用.此时,每次迭代时List<Person>都会迭代对相同对象的引用,因此在一个循环中进行的任何修改都将在另一个循环中看到.
如果您将日志记录(或断点)放入其中,您可能会发现更容易理解发生了什么GetPeople().我有一篇文章介绍了实现细节,这可能会使事情变得更加清晰.
| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |