【问题标题】:Possible to modify a List while iterating through it?可以在迭代列表时修改它吗?
【发布时间】:2022-01-05 22:37:36
【问题描述】:

我有以下几点:

foreach (var depthCard in depthCards)
{
    var card = InternalGetCard(db, depthCard.CardId);
    var set = InternalGetSet(db, (int)card.ParentSetId);
    var depthArray = InternalGetDepthArrayForCard(db, set.SetId);
    foreach (var cardToUpdate in set.Cards)
    {
        // do stuff
        SaveChanges(db);
        // since I already took care of it here, remove from depthCards
        depthCards.Remove(depthCardToUpdate);
    }
}

这不起作用,因为我正在循环中间修改集合。是否有某种类型的集合允许这种类型的访问?

我不想ToList()depthCards,因为我已经拥有它们并且我想要在迭代时修改该列表。这可能吗?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    有可能,诀窍是向后迭代:

    for (int i = depthCards.Count - 1; i >= 0; i--) {
      if (depthCards[i] == something) { // condition to remove element, if applicable
         depthCards.RemoveAt(i);
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用 for-loop 向后迭代

      for (int i = depthCards.Count - 1; i >= 0; i--)
      {
          depthCards.RemoveAt(i);
      }
      

      或者,如果您只想删除某个条件下的项目,请使用List.RemoveAll

      depthCardToUpdate.RemoveAll(dc => conditionHere);
      

      【讨论】:

      • 可以在执行 ForEach() 之前添加一个 Where() 语句以在删除它们之前缩小结果,如果它是有条件的删除。
      • @Bob.: 不,因为那样它就不再是List<T>,而是一个不支持List.ForEach 方法的IEnumerable<T>。那时你只能使用foreach,但是不能在循环中修改列表。
      • 这不是ToList() 的用途吗?
      • 否,ToList 创建一个新列表。因此,您将内存消耗翻倍(在最好的情况下)。
      • @Vringar:你说得对,可能行不通。文档说:“不支持修改 Action 委托主体中的基础集合,并导致未定义的行为。”删除了这种方法。谢谢
      【解决方案3】:

      您可以创建一个自定义枚举器来为您处理此问题。我做过一次,有点棘手,但经过一些技巧后就成功了。

      见:http://www.codeproject.com/Articles/28963/Custom-Enumerators

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-05
        • 2014-09-17
        • 2017-12-05
        • 2019-04-04
        • 2020-07-26
        • 1970-01-01
        相关资源
        最近更新 更多