【问题标题】:How to use foreach loop with changing its range in C# [duplicate]如何在 C# 中使用 foreach 循环更改其范围 [重复]
【发布时间】:2023-03-28 06:10:01
【问题描述】:

由于 ClientStack.Children 成员(文本块)被删除后 ClientStack.Children 范围发生变化,因此引发异常:

foreach (TextBlock textblock in ClientStack.Children)
{
    if ((string)textblock.ToolTip == e.IP)
    {
        ClientStack.Children.Remove(textblock);
        // update foreach loop's range???
    }
}

有没有办法在 ClientStack.Children 成员被删除后更新这个 foreach 循环的范围?

【问题讨论】:

  • 什么是ClientStack.Children
  • @TimSchmelter ClientStack 是一个 StackPanel,ClientStack.Children 是它的内容,在我的例子中是 TextBlocks
  • 据我所知不支持。您可以按索引进行迭代,也可以列出要删除的项目,然后在循环后进行实际删除。

标签: c# loops foreach range


【解决方案1】:

在枚举集合时不能修改集合,因此会出现异常。

您可以使用向后的for-loop

for(int i = ClientStack.Children.Count - 1; i >= 0; i--)
{
    if (((string)ClientStack.Children[i]).ToolTip == e.IP)
    {
        ClientStack.Children.RemoveAt(i);
    }
}

另一种 - 效率稍低 - 方法是使用删除集合:

var removeBlocks = ClientStack.Children.Cast<object>()
    .Where(textblock => ((string)textblock).ToolTip == e.IP)
    .ToList();
removeBlocks.ForEach(ClientStack.Children.Remove); 

【讨论】:

  • 我认为在删除基于索引时是RemoveAt
  • @CSharpie:是的,谢谢,已修复
  • 最好从stackoverflow.com/a/1582317 等高度支持的答案中复制粘贴代码,以避免冒着错误自己实现的风险... :)
  • reverse for+RemoveAt 是所有实现 IList 的方法。
【解决方案2】:

迭代时无法更新范围。而是制作集合的副本并对其进行迭代,但从原始集合中删除。

foreach (TextBlock textblock in ClientStack.Children.ToList())
{
    if ((string)textblock.ToolTip == e.IP)
    {
        ClientStack.Children.Remove(textblock);
    }
}

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 2010-11-10
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多