c# – 为什么我必须创建`IEnumerable`的具体实现才能修改其成员
发布时间:2020-12-16 00:18:26  所属栏目:百科  来源:网络整理 
            导读:为什么我必须创建IEnumerable T的具体实现?为了修改foreach循环中的成员? This blog post (Exhibit 1)解释了这种行为,但我无法完全理解它. 我在这里有一个非常简单的代码片段来重现这个问题(C#4.0 / .NET 4.0). class Person{ public int Age { get; set;
                
                
                
            | 
                         
 为什么我必须创建IEnumerable< T>的具体实现?为了修改foreach循环中的成员? 
  
  
This blog post (Exhibit 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(); 
        }
    }
}
解决方法
 每次迭代人员时,它都会再次执行GetPeople()中的代码 – 创建Person的新实例.当你调用GetPeople()时,GetPeople中的代码不会运行;它只在你打电话时开始运行: 
  
  
  
        var iterator = people.GetEnumerator(); iterator.MoveNext(); …这是foreach循环的作用. 如果调用ToList(),这意味着您只需执行一次GetPeople()中的代码,并存储迭代序列时返回的引用.此时,每次迭代List< Person>您将迭代对相同对象的引用,因此您在一个循环中进行的任何修改都将在另一个循环中看到. 如果将记录(或断点)放在GetPeople()中,您可能会发现更容易理解发生了什么.我有一个article进入实现细节,这可能会使事情更清晰. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
