gpt4 book ai didi

C# 在使用 ForEach 枚举时修改 IEnumerable

转载 作者:太空狗 更新时间:2023-10-30 00:35:15 24 4
gpt4 key购买 nike

这是我正在探索的东西,看看我是否可以接受以前的东西

List<MdiChild> openMdiChildren = new List<MdiChild>();
foreach(child in MdiManager.Pages)
{
openMdiChildren.Add(child);
}

foreach(child in openMdiChild)
{
child.Close();
}

并将其缩短为不需要 2 个 foreach 循环。

注意 我更改了对象的名称以简化此示例(这些来自第 3 方控件)。但为了信息和理解MdiManager.Pages 继承了 CollectionBase 的形式,后者又继承了 IEnumerable

MdiChild.Close()MdiManager.Pages 集合中删除打开的子项,从而改变集合并导致枚举在集合被删除时抛出异常在枚举期间修改,例如..

foreach(child in MdiManage.Pages)
{
child.Close();
}

我能够将工作双 foreach

((IEnumerable) MdiManager.Pages).Cast<MdiChild>.ToList()
.ForEach(new Action<MdiChild>(c => c.Close());

为什么在枚举期间处理修改集合时没有同样的问题?我最好的猜测是,当枚举 ToList 调用创建的列表时,它实际上是在 MdiManager.Pages 集合中的匹配项上执行操作,而不是生成的列表。

编辑

我想说清楚,我的问题是如何简化它,我只是想了解为什么在我执行集合时修改集合没有问题,就像我目前编写的那样。

最佳答案

您调用 ToList()是什么拯救了你,因为它本质上是在重复你在上面所做的事情。 ToList()实际上创建了一个 List<T> (本例中为 List<MdiChild>)包含 MdiManager.Pages 中的所有元素,然后您随后调用 ForEach那个 列表上操作,而不是在MdiManager.Pages 上操作.

归根结底,这是一个风格偏好的问题。我个人不是 ForEach 的粉丝函数(我更喜欢像 WhereToList() 这样的查询组合函数,因为它们很简单,而且它们的设计不会对原始源产生副作用,而 ForEach 则不会)。

你也可以这样做:

foreach(child in MdiManager.Pages.Cast<MdiChild>().ToList())
{
child.Close();
}

从根本上说,所有三种方法都做完全相同的事情(它们将 MdiManager.Pages 的内容缓存到 List<MdiChild> 中,然后遍历该缓存列表并在每个元素上调用 Close()

关于C# 在使用 ForEach 枚举时修改 IEnumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5265453/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com