2012-04-16 2 views
12

은 내가 볼 수있는 LINQ와 foreach 문을 삭제 하시겠습니까?안쪽이 허용되지 않는 이유

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

왜 이것이 실패하는지 이해할 수 없습니다. "Where()"메서드는 분명 원래 컬렉션을 반환하지 않으므로 원본 컬렉션을 제거하려고 할 때 원래 컬렉션을 열거하지 않습니다.

+0

나는이 "사물"에 대해 얻지 못하는 것이 있습니다. 그 타입의 물건이 틀림없이 그것 인 것은 틀림 이냐? 누군가가 나를 계몽 .... – Deb

+0

질문이 혼란 스러울 경우 죄송합니다. 어떤 수업이든 가능하고 myCollecion은 ICollection 입니다. FWIW 에릭은 내 원래의 질문을 완전히 이해하고 답변했기 때문에 내가 생각하는 한 폐쇄적이다. – Andy

답변

26

왜 이것이 실패하는지 이해할 수 없습니다.

다음 질문은 "왜 이것이 실패합니까?"라고 가정합니다. (당신은 실제로 귀하의 질문에 질문을 잊어 버렸습니다.)은 "()"방법은 분명히

올바른 원래의 모음을 반환하지 않습니다

. "Where"는 필터가 위에있는 컬렉션을 나타내는 IEnumerable<T>을 반환합니다.

그래서 나는 그것을 제거하려고 할 때 원본 컬렉션 라운드를 열거하지 않을 것입니다.

잘못된 것입니다. 은 원래 컬렉션을 열거하는입니다. 위에 필터를 넣은 원래 컬렉션 을 열거했습니다.

"Where"를 호출하면 열심히 필터를 평가하지 않고 원본 컬렉션의 새 복사본에 적용하여 필터를 적용합니다. 오히려 원본 컬렉션을 열거하지만 필터와 일치하지 않는 항목은 건너 뜁니다.

상점에서 "모든 것을 보여주세요"라고 말하면 모든 것을 보여주는 사람이 모든 것을 보여줍니다. "이제 1kg에 1 달러에서 5 달러 사이 인 사과를 보여주세요"라고 말하면 은 사과 만있는 완전히 새로운 저장소를 구성하지 않고 있습니다..이전과 완전히 동일한 컬렉션을 찾고 있습니다. 필터가있는 상태입니다.

2

foreach 루프를 사용하여 컬렉션을 수정하면 안됩니다. 전체 foreach 루프가 실행되기 전에 삭제하려고 시도합니다. 그러므로 그것은 실패 할 것이다.

+1

나는 당신이 대답의 두 번째 부분과 가깝다고 생각합니다. 당신은 게으른 평가를 찾고 있습니까? –

6

두 번째 명령문은 IEnumerable<>을 목록에 반환합니다. 이 사람은 괜찮을 것 같네요 :

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

+1은 IEnumerable –

+0

을 언급 한 것에 대해 감사합니다. 이것은 구현 한 솔루션입니다. 그러나 실제로 내가 원했던 것은 Eric이 아래에 무슨 일이 있었는지 알았 기 때문입니다. – Andy

12

에 한번 사용이 코드

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

당신은 할 수 있습니다 : 확장 메서드는 전달 된 조건에 따라 컬렉션 값을 필터링하고 IEnumerable을 반환

myCollection.RemoveAll(shouldDelete); 
+0

감사합니다. 실제로 루프 내부에 다른 것을하고 싶었습니다. 그래서 Likurg의 제안은 나에게 더 좋았지 만 +1을했는데 :-) – Andy

+2

... 'myCollection'의 유형에 RemoveAll 메소드가있는 경우! 'List '은 그렇지만 많은 컬렉션 유형은 그렇지 않습니다. – phoog

1

. 따라서 반복되는 동안 컬렉션을 수정할 수 없습니다.

용도에 따라 RemoveAll()을 사용할 수 있습니다.

관련 문제