加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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进入实现细节,这可能会使事情更清晰.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读