在 for 循环中修改 IEnumerable

Modifiying IEnuemerable in for loops

如何修改 IEnuemerable<ProductLineDto>

中的嵌套元素

所以基本上循环看起来像这样 product lines > project types > projects > sub projects > 由更多 sub projectsactivities.

问题是我无法修改 subprojectactivities,这应该在递归函数 GetActivitiesForActivityPerson

中发生
        private IEnumerable<ProductLineDto> GetGanttDataByPerson(IEnumerable<ProductLineDto> ganttData, GanttFilterDto ganttFilterDataModel)
        {
            if(ganttFilterDataModel.PersonId == null)
                return ganttData;

            var gdata = ganttData.CopyProductLineDtosEnumerable().ToList();

            for(var i = 0; i < gdata.Count; i++)
            {
                    var pType = gdata[i].ProjectType.CopyProjectTypeDtoEnumerable().ToList();

                    for (var j = 0; j < pType.Count; j++)
                    {
                        var projects = pType[j].Projects.CopyProjectDtosEnumerable().ToList();
                        for (var a = 0; a < projects.Count; a++)
                        {
                            // projects[a].Children is not being modified
                            projects[a].Children = GetActivitiesForActivityPerson(projects[a].Children, ganttFilterDataModel.PersonId);
                        }
                        pType[j].Projects = projects;
                    }

                gdata[i].ProjectType = pType;
            }

            ganttData = gdata;
            return ganttData; ;
        }

这里是递归函数

    private IEnumerable<SubProjectDto> GetActivitiesForActivityPerson(IEnumerable<SubProjectDto> children, Guid? personId)
    {
        var subProjects = children.CopySubProjectDtoEnumerable().ToList();

        for (var i = 0; i < subProjects.Count; i++)
        {
            var acts = subProjects[i].Activities.CopyActivityDtoEnumerable().ToList();

            acts.RemoveAll(activity => activity.ActivityPersons.All(person => person.PersonID != personId));

            subProjects[i].Activities = acts;

            if(subProjects[i].Children.Any())
                GetActivitiesForActivityPerson(subProjects[i].Children, personId);
        }

        children = subProjects;
        return children;
    }

当我逐步执行递归函数时,return children 语句由修改后的 activities 组成。然而,这行代码并不包含修改后的 activities 它包含赋值调用后的原始数据集。

projects[a].Children = GetActivitiesForActivityPerson(projects[a].Children, ganttFilterDataModel.PersonId);

如果有人想知道所有复制方法是什么样的,他们只是 return DTO.

的一个新实例

例如

    public static IEnumerable<ProjectTypeDto> CopyProjectTypeDtoEnumerable(this IEnumerable<ProjectTypeDto> projectTypes)
    {
        return projectTypes.Select(x => new ProjectTypeDto
        {
            ProjectTypeId = x.ProjectTypeId,
            Description = x.Description,
            RowId = x.RowId,
            Projects = x.Projects.CopyProjectDtosEnumerable()
        });
    }

为了将来参考,请提交可执行代码摘录。为了获得最佳结果,您希望人们能够将您的问题代码直接复制粘贴到他们的 IDE 中进行操作。

此外,代码非常复杂。它简化为:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Whosebug_LoopMadness
{
    class Program
    {
        static void Main(string[] args)
        {
            // ???
        }

        private static IEnumerable<ProductLineDto> GetGanttDataByPerson(IEnumerable<ProductLineDto> ganttData, GanttFilterDto ganttFilterDataModel)
        {
            if (ganttFilterDataModel.PersonId == null)
                return ganttData;

            foreach (var pType in ganttData)
            {
                foreach (var project in pType.Projects)
                { 
                    project.Children = GetActivitiesForActivityPerson(project.Children, ganttFilterDataModel.PersonId);
                }
            }
            return ganttData;
        }

        private static IEnumerable<SubProjectDto> GetActivitiesForActivityPerson(IEnumerable<SubProjectDto> children, Guid? personId)
        {
            foreach (var subProject in children)
            {
                subProject.Activities = subProject.Activities.Where(a => a.ActivityPersons.All(person => person.PersonID != personId));

                if (subProject.Children.Any())
                {
                    GetActivitiesForActivityPerson(subProject.Children, personId);
                }
            }
            return children;
        }
    }

    class SubProjectDto
    {
        public IEnumerable<Activity> Activities { get; internal set; }
        public IEnumerable<SubProjectDto> Children { get; internal set; }
    }

    class Activity
    {
        public IList<ActivityPerson> ActivityPersons { get; internal set; }
    }

    class ActivityPerson
    {
        public Guid? PersonID { get; internal set; }
    }

    class GanttFilterDto
    {
        public Guid PersonId { get; internal set; }
    }

    class ProductLineDto
    {
        public IList<Project> Projects { get; internal set; }
    }

    class Project
    {
        public IEnumerable<SubProjectDto> Children { get; set; }
    }
}

如您所见,将 for 循环替换为 foreach 循环大大减少了代码量并提高了可读性。无关的副本列表已被删除。而且,我必须通过猜测创建6个数据类才能编译。

我放弃了为这个程序寻找合适的驱动程序。但是,我相信修改嵌套元素的问题已经解决了,因为编辑的变量只是通过引用传递。

我认为您的问题源于对按值传递与引用传递的不完全理解,因此您对深拷贝的混淆使用。微软解释得比我好,所以请看这个link.