2010-06-08 34 views
8

Tôi có phương pháp sau, tôi muốn xóa các mục khỏi bộ sưu tập của mình khớp với Id sản phẩm. Có vẻ khá thẳng về phía trước, nhưng tôi nhận được một ngoại lệ. Về cơ bản, bộ sưu tập của tôi không được đồng bộ hóa. Vì vậy, cách tốt nhất để loại bỏ một mục từ một bộ sưu tập là gì.xóa các mục khỏi Danh sách chung <t>

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

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

Chi tiết ngoại lệ: System.InvalidOperationException: Bộ sưu tập đã được sửa đổi; hoạt động điều tra có thể không thực thi

Trả lời

27

Sửa đổi bộ sưu tập trong vòng lặp không hoạt động. Để giải quyết vấn đề đó, List có một vài phương pháp cho phép sửa đổi "hàng loạt" của một bộ sưu tập. Trong trường hợp của bạn, hãy sử dụng:

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

cảm ơn conrad, thật lạ là tôi không thể đưa lamda vào làm việc. Nó không nhận ra phần "x.Product.Id". Strange cos các công trình sau đây var truy vấn = từ x trong currentOrder.OrderItems nơi x.Product.Id == productId select x; Loại bộ sưu tập là ISet. – frosty

+0

ok, tôi đã trả lời câu hỏi của riêng mình :) Tôi đã thay đổi điều này thành Danh sách frosty

4

Bạn không thể sửa đổi bộ sưu tập trong khi lặp lại bộ sưu tập đó. Chỉ cần sử dụng vòng lặp for bình thường thay vì vòng lặp foreach.

+0

:) đây là giải pháp tốt nhất cho tôi – EagleFox

2

Bạn không thể xóa một mục từ một bộ sưu tập bạn đang lặp qua, bạn có thể theo dõi các OrderItem, sau đó loại bỏ nó sau khi bạn hoàn thành vòng lặp

3

By looping cách này bạn không thể xoá các mục bởi vì trong nó bộ sưu tập nó giữ theo dõi các mục được lưu trữ.

Cách dễ dàng để làm điều này:

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

hoặc

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

Như bạn nhận ra rằng bạn không thể loại bỏ một mục từ một bộ sưu tập khi bạn đang lặp qua nó. Tôi chắc chắn một người nào đó sẽ có thể cung cấp một giải pháp gọn gàng LINQ nhưng sau sẽ giúp bạn đi ban đầu:

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 ra giải pháp LINQ – openshac

+0

Lưu ý rằng 'List .RemoveAll' có sẵn trong .NET 2.0 và về mặt kỹ thuật không phải LINQ, mặc dù có vẻ tương tự. Đó là một lợi thế lớn so với LINQ cho những linh hồn nghèo nàn đó phải duy trì tính tương thích của Windows 2000. – OregonGhost

0

"foreach" cung cấp một "Forward-only read-only" lặp đi lặp lại của một bộ sưu tập.

Để giải quyết sự cố này, bạn có thể sao chép tham chiếu đến bộ sưu tập khác và sau đó lặp lại trên bộ sưu tập đã sao chép và xóa các mục khỏi bộ sưu tập gốc.

Các vấn đề liên quan