2010-06-08 7 views
8

Je possède la méthode suivante, je souhaite supprimer les éléments de ma collection qui correspondent à l'ID du produit. Semble assez simple, mais je reçois une exception. Fondamentalement, ma collection est en train de se désynchroniser. Alors, quelle est la meilleure façon de supprimer un élément d'une collection.supprimer des éléments d'une liste générique <t>

public void RemoveOrderItem(Model.Order currentOrder, int productId) 
{ 

    foreach (var orderItem in currentOrder.OrderItems) 
    { 
     if (orderItem.Product.Id == productId) 
     { 
      currentOrder.OrderItems.Remove(orderItem); 
     } 
    } 
} 

Détails d'exception: System.InvalidOperationException: la collection a été modifiée; l'opération d'énumération peut ne pas s'exécuter.

Répondre

27

La modification d'une collection à l'intérieur d'une boucle ne fonctionne pas. Pour contourner cela, List a quelques méthodes qui permettent des modifications «par lots» d'une collection. Dans votre cas, utilisez:

currentOrder.OrderItems.RemoveAll(x => x.Product.Id == productId) 
+0

merci conrad, bizarrement, je ne peux pas obtenir le lamda pour travailler. Il ne reconnaît pas la partie "x.Product.Id". Étrange cos les travaux suivants var query = de x dans currentOrder.OrderItems où x.Product.Id == productId select x; Le type de collection est ISet. – frosty

+0

ok, j'ai répondu à ma propre question :) Je l'ai changé à la liste frosty

4

Vous ne pouvez pas modifier une collection en l'itérant. Utilisez simplement une boucle normale for au lieu d'une boucle foreach.

+0

:) ce fut la meilleure solution pour moi – EagleFox

2

Vous ne pouvez pas supprimer un élément d'une collection que vous Itère, vous pourriez garder une trace du OrderItem, puis retirez-le après avoir terminé en boucle

3

En boucle cette façon, vous ne pouvez pas supprimer des éléments parce que ses dans collection il garde la trace des articles stockés.

façon facile de le faire:

authorsList.RemoveAll(x => x.ProductId == productId); 

ou

authorsList = authorsList.Where(x => x.ProductId!= productId).ToList(); 
1

Comme vous réalisez que vous ne pouvez pas supprimer un élément d'une collection pendant que vous Looping dessus. Je suis sûr que quelqu'un sera en mesure de fourni une solution plus propre LINQ, mais ce qui suit devrait vous permettre d'aller d'abord:

public void RemoveOrderItem(Model.Order currentOrder, int productId) 
{ 
    var selectedOrderItem = null; 
    foreach (var orderItem in currentOrder.OrderItems) 
    { 
     if (orderItem.Product.Id == productId) 
     { 
      selectedOrderItem = orderItem; 
      break; 
     } 
    } 

    if(selectedOrderItem != null) 
     currentOrder.OrderItems.Remove(selectedOrderItem); 
} 
+0

Konrad Rudolph a donné la solution LINQ – openshac

+0

Notez que 'Liste .RemoveAll' est disponible dans .NET 2.0 et n'est techniquement pas LINQ, bien qu'il semble similaire. C'est un énorme avantage par rapport à LINQ pour les pauvres âmes qui doivent maintenir la compatibilité avec Windows 2000. – OregonGhost

0

itération d'une collection « foreach » fournit un « Forward seule lecture seule ». Pour contourner ce problème, vous pouvez copier la référence vers une autre collection, puis itérer sur la collection copiée et supprimer les éléments de la collection d'origine.

Questions connexes