C#에서 열거(enumerable)에 대한 작업을 실행할 때에 다음과 같은 오류를 마주하는 경우가 있습니다. 이를 해결하는 방법에 대해 알아보도록 합시다.
- System.InvalidOperationException: 컬렉션이 수정되었습니다. 열거 작업이 실행되지 않을 수 있습니다.
- 위치: System.Data.RBTree`1.RBTreeEnumerator.MoveNext()
- 위치: Namespace_Name.Class_Name.Method_Name()
이번 예제에서는 foreach 루프를 사용하여 반복 중에 컬렉션을 수정하려고 할 때 발생하도록 해보았습니다. 특히 특정 조건에 따라 DataTable에서 행을 삭제하려고 시도한 다음, 해당 수정사항을 반영하고 다시 테이블에 접근하는 경우에 나타난답니다.
DataTable dataTable = new DataTable();
List<string> strToDelete = new List<string>();
foreach (string str in strToDelete)
{
foreach (DataRow dataRow in dataTable.Rows)
{
if (strToDelete.Contains(dataRow["column"].ToString()))
{
dataRow.Delete();
//컬렉션이 수정되었습니다. 열거 작업이 실행되지 않을 수 있습니다.
dataTable.AcceptChanges();
}
}
//dataTable.AcceptChanges();
}
이 예외를 피하기 위해서는 컬렉션을 반복 중에 수정사항을 커밋하는 부분을 잘 검토해야 합니다. 반복이 완료된 후에 적용하는 방식을 고려하는 것이 바람직할 것입니다.
먼저 삭제할 행을 모두 처리하고 반복 구문의 외부에서 'AcceptChanges' 메서드를 호출하여 InvalidOperationException을 방지할 수 있습니다.
딕셔너리에서 키에 대한 밸류를 수정하려다가 오류가 발생하는 경우에는 foreach 대신, for 구문을 사용하세요.
Dictionary<int, string> dictionary = new Dictionary<int, string>();
// dictionary에 값 추가
for (int i = 0; i < dictionary.Count; i++)
{
KeyValuePair<int, string> p = dictionary.ElementAt(i);
}