루프에서 열거하는 동안 컬렉션에서 항목을 제거하려는 고전적인 경우가 있습니다.
List<int> myIntCollection = new List<int>();
myIntCollection.Add(42);
myIntCollection.Add(12);
myIntCollection.Add(96);
myIntCollection.Add(25);
foreach (int i in myIntCollection)
{
if (i == 42)
myIntCollection.Remove(96); // The error is here.
if (i == 25)
myIntCollection.Remove(42); // The error is here.
}
변경이 발생한 후 반복이 시작될 InvalidOperationException
때 열거자가 기본 컬렉션이 변경되는시기를 좋아하지 않기 때문에가 발생합니다.
반복하는 동안 컬렉션을 변경해야합니다. 이를 방지하는 데 사용할 수있는 패턴 이 많이 있지만 그중 어느 것도 좋은 해결책이없는 것 같습니다.
이 루프 내부를 삭제하지 말고 대신 메인 루프 이후에 처리하는 별도의 "삭제 목록"을 유지하십시오.
이것은 일반적으로 좋은 해결책이지만 제 경우에는 항목을 실제로 삭제하기 위해 항목을 실제로 삭제하기 위해 코드의 논리 흐름이 변경 될 때까지 항목이 "대기"상태로 즉시 사라져야합니다.
항목을 삭제하는 대신 항목에 플래그를 설정하고 비활성으로 표시하면됩니다. 그런 다음 패턴 1의 기능을 추가하여 목록을 정리하십시오.
이 것이 내 요구 모두를 위해 작동하지만 그것은 것을 의미합니다 많은 코드가 비활성 플래그를 항목에 액세스 할 때마다 시간을 확인하기 위해 변경해야합니다. 이것은 내 취향에 비해 너무 많은 관리입니다.
어떻게 든 패턴 2의 아이디어를
List<T>
. 이 수퍼리스트는 비활성 플래그, 팩트 이후의 객체 삭제를 처리하고 비활성으로 표시된 항목을 열거 소비자에게 노출하지 않습니다. 기본적으로 패턴 2 (및 이후 패턴 1)의 모든 아이디어를 캡슐화합니다.이와 같은 클래스가 있습니까? 누구든지 이것에 대한 코드가 있습니까? 아니면 더 좋은 방법이 있습니까?
myIntCollection.ToArray()
대신 액세스myIntCollection
하면 문제가 해결되고 루프 내부에서 삭제할 수 있다고 들었습니다 .이것은 나에게 나쁜 디자인 패턴처럼 보이거나 괜찮을까요?
세부:
목록에는 많은 항목이 포함되며 그중 일부만 제거합니다.
루프 내에서 모든 종류의 프로세스, 추가, 제거 등을 수행 할 것이므로 솔루션은 상당히 일반적이어야합니다.
삭제해야하는 항목이 루프의 현재 항목 이 아닐 수 있습니다. 예를 들어, 30 개 항목 루프의 항목 10에 있고 항목 6 또는 항목 26을 제거해야 할 수 있습니다.이 때문에 배열을 뒤로 걸어가는 작업이 더 이상 작동하지 않습니다. ;영형(