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

在foreach中的Enumerable.Where中无法访问C#对象属性

发布时间:2020-12-15 23:24:05 所属栏目:百科 来源:网络整理
导读:发现了一个c#head-scratcher.在foreach循环中,直接在Enumerable.Where中使用parent.Id属性不起作用.首先将它放在一个变量中.在Select语句中直接访问parent.Id没有问题. ListPerson people = new ListPerson() { new Person() { Id = 1,name = "John",parentI
发现了一个c#head-scratcher.在foreach循环中,直接在Enumerable.Where中使用parent.Id属性不起作用.首先将它放在一个变量中.在Select语句中直接访问parent.Id没有问题.

List<Person> people = new List<Person>() { 
        new Person() { Id = 1,name = "John",parentId = null },new Person() { Id = 2,name = "Sarah",new Person() { Id = 3,name = "Daniel",parentId = 1 },new Person() { Id = 4,name = "Peter",parentId = 1 }
    };

    List<object> peopleTree = new List<object>();

    var parents = people.Where(p => !p.parentId.HasValue);
    foreach (Person parent in parents)
    {
        int parentId = parent.Id;
        var children = people
            //.Where(p => p.parentId.Equals(parentId)) //This works,is able to find the children
            .Where(p => p.parentId.Equals(parent.Id)) //This does not work,no children for John
            .Select(p => new { Id = p.Id,Name = p.name,pId = parent.Id }); //pId set correctly

        peopleTree.Add(new
        {
            Id = parent.Id,Name = parent.name,Children = children
        });
    }

或者,如果我使用for循环并将parent放在变量中,我可以直接在Where语句中访问parent.Id属性.

var parents = people.Where(p => !p.parentId.HasValue).ToArray();
for (int idx = 0; idx < parents.Count(); idx++)
{
    var parent = parents[idx];
...

我无法找到它为何如此行为的答案.
有人能解释一下吗?

解决方法

此问题是由子项的延迟执行创建的.从本质上讲,评估孩子时父母的价值是不同的. Geekspeak为此是 Accessing Modified Closure.

您可以通过引入临时方式来修复它,或者在foreach循环仍在当前迭代中时强制进行评估:

var children = people
    .Where(p => p.parentId.Equals(parent.Id))
    .Select(p => new { Id = p.Id,pId = parent.Id })
    .ToList();

(编辑:李大同)

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

    推荐文章
      热点阅读