2012-04-16 48 views
12

tôi có thể thấy tại sao điều này là không được phép:Xóa foreach bên trong với LINQ nơi

foreach (Thing t in myCollection) { 
    if (shouldDelete(t) { 
     myCollection.Delete(t); 
    } 
} 

nhưng làm thế nào về điều này?

foreach (Thing t in myCollection.Where(o=>shouldDelete(o)) { 
    myCollection.Delete(t); 
} 

Tôi không hiểu tại sao điều này không thành công. Phương thức "Where()" rõ ràng không trả về bộ sưu tập gốc, vì vậy tôi không liệt kê vòng bộ sưu tập ban đầu khi tôi cố xóa một thứ gì đó khỏi bộ sưu tập đó.

+0

Có điều gì đó mà tôi không hiểu về điều "Điều" này. Nó chắc chắn không phải là một loại được xây dựng trong điều đó là nó? ai đó khai sáng cho tôi ... – Deb

+0

Xin lỗi nếu câu hỏi khó hiểu. Điều đó có thể là bất kỳ lớp nào và myCollecion là bất kỳ ICollection nào. FWIW Eric đã hoàn toàn hiểu và trả lời câu hỏi ban đầu của tôi vì vậy nó đóng cửa theo như tôi quan tâm. – Andy

Trả lời

26

Tôi không hiểu tại sao điều này không thành công.

Tôi cho rằng câu hỏi của bạn là "tại sao điều này không thành công?" (Bạn quên thực sự đặt một câu hỏi trong câu hỏi của bạn.)

Các "Where()" phương pháp rõ ràng là không được trả lại bộ sưu tập gốc

đúng. "Nơi" trả về một số IEnumerable<T> đại diện cho bộ sưu tập có bộ lọc được đặt trên đầu trang của nó.

vì vậy tôi không liệt kê vòng bộ sưu tập gốc khi tôi cố xóa một thứ gì đó khỏi bộ sưu tập gốc.

Không chính xác. Bạn liệt kê bộ sưu tập gốc. Bạn đang liệt kê bộ sưu tập gốc với bộ lọc được đặt ở trên cùng của nó.

Khi bạn gọi "Nơi", nó không háo hức đánh giá bộ lọc và tạo bản sao hoàn toàn mới của bộ sưu tập gốc với bộ lọc được áp dụng cho bộ lọc đó. Thay vào đó, nó cung cấp cho bạn một đối tượng liệt kê bộ sưu tập gốc, nhưng bỏ qua các mục không khớp với bộ lọc.

Khi bạn đang ở cửa hàng và bạn nói "chỉ cho tôi mọi thứ", anh chàng cho bạn thấy mọi thứ hiển thị cho bạn mọi thứ. Khi bạn nói "bây giờ chỉ cho tôi thấy những quả táo nằm trong khoảng từ $ 1 đến $ 5 một kilôgam", bạn không xây dựng một cửa hàng hoàn toàn mới chỉ có táo trong nó.Bạn đang xem chính xác cùng một bộ sưu tập các nội dung như trước đây, chỉ với một bộ lọc trên đó.

2

Đó là do bộ sưu tập không được sửa đổi với vòng lặp foreach. Nó cố gắng xóa nó trước khi toàn bộ vòng lặp foreach được thực hiện. Do đó nó sẽ thất bại.

+1

Tôi nghĩ rằng bạn đang gần với phần thứ hai của câu trả lời của bạn ... là bạn đang tìm kiếm đánh giá lười biếng? –

6

Câu lệnh thứ hai trả về số IEnumerable<> hoạt động trên danh sách của bạn. Cái này sẽ không sao:

foreach (Thing t in myCollection.Where(o=>shouldDelete(o).ToList()) { 
    myCollection.Delete(t); 
} 
+0

1 để đề cập đến IEnumerable –

+0

cảm ơn, đây là giải pháp tôi đã triển khai, nhưng tôi đánh dấu Eric là câu trả lời vì điều tôi thực sự muốn biết điều gì đang xảy ra bên dưới – Andy

12

Hãy thử sử dụng mã này

myCollection.RemoveAll(x => x.shouldDelete(x)); 
9

Bạn có thể làm:

myCollection.RemoveAll(shouldDelete); 
+0

Cảm ơn, tôi thực sự muốn làm điều gì khác bên trong vòng lặp vì vậy đề nghị của Likurg tốt hơn cho tôi, nhưng tôi đã +1 bạn :-) – Andy

+2

... nếu loại 'myCollection' có phương thức RemoveAll! 'Danh sách ' hiện, nhưng nhiều loại bộ sưu tập thì không. – phoog

1

đâu phương pháp khuyến nông lọc các giá trị bộ sưu tập dựa trên vị trôi qua và trả IEnumerable . Do đó không thể sửa đổi bộ sưu tập trong khi lặp lại.

Bạn có thể sử dụng RemoveAll() cho mục đích của mình.

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