在 for 循环中修改 IEnumerable
Modifiying IEnuemerable in for loops
如何修改 IEnuemerable<ProductLineDto>
中的嵌套元素
所以基本上循环看起来像这样 product lines
> project types
> projects
> sub projects
> 由更多 sub projects
和 activities
.
问题是我无法修改 subproject
的 activities
,这应该在递归函数 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.
如何修改 IEnuemerable<ProductLineDto>
所以基本上循环看起来像这样 product lines
> project types
> projects
> sub projects
> 由更多 sub projects
和 activities
.
问题是我无法修改 subproject
的 activities
,这应该在递归函数 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.