| 에러 내용
컬렉션을 사용하다 발생한 에러입니다.
이 에러는 프로그램이 컬렉션을 순회하고 있는 동안 컬렉션이 변경되었을 때 발생하는 에러입니다.
컬렉션을 순회하는 도중에는 원소를 추가하거나 제거하는 등의 작업을 수행하면 안 됩니다.
이러한 작업이 발생하면 컬렉션의 상태가 변경되고, 이는 열거 작업에 영향을 미칩니다.
그렇기 때문에 .Net은 이런 상황을 예방하기 위해 이런 종류의 에러를 발생시킵니다.
예제) System.InvalidOperationException 에러 발생 상황
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
if (number == 3)
{
numbers.Remove(number);
}
}
위 코드는 1부터 5까지의 숫자를 담은 리스트에서 숫자 3을 찾아 제거하려고 하는 코드입니다.
하지만 foreach를 통해 리스트를 순회하는 도중에 리스트에서 원소를 제거하려 하므로 에러가 발생합니다.
| 에러 해결 방법
이 문제를 해결하려면 원본 컬렉션을 바로 수정하는 것이 아니라,
복사본을 만들고 작업하면 해결할 수 있습니다.
예제) 컬렉션의 복사본을 만들어 컬렉션 수정
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
List<int> numbersCopy = new List<int>(numbers);
foreach (int number in numbersCopy)
{
if (number == 3)
{
numbers.Remove(number);
}
}
원본 컬렉션인 'numbers'를 순회하는 것이 아니라
복사본인 'numbersCopy'를 순회하므로, 원본 컬렉션을 수정하는 데 문제가 없습니다.
따라서 에러가 발생하지 않습니다.
예제) 크기가 큰 컬렉션의 순회
컬렉션의 크기가 너무 크다면, 컬렉션의 복사본을 만드는 것은 메모리 사용 측면에서 비효율적입니다.
이런 경우, 리스트나 배열 대신 LinkedList 같은 다른 컬렉션 타입을 사용하거나,
원본 컬렉션을 복사하지 않는 방법으로 문제를 접근해야 합니다.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
for (int i = numbers.Count - 1; i >= 0; i--)
{
if (numbers[i] == 3)
{
numbers.RemoveAt(i);
}
}
예를 들어, for 루프와 RemoveAt 메서드를 사용해 뒤에서부터 컬렉션을 순회하며 원소를 제거하는 방법이 있습니다.
이렇게 하면 컬렉션을 순회하는 동안 발생하는 인덱스 변화를 피할 수 있습니다.
위 코드는 리스트의 끝에서부터 시작해서 앞으로 이동하며, 숫자 3을 찾으면 그 위치의 원소를 제거하는 코드입니다.
뒤에서부터 순회하기 때문에 원소를 제거하더라도 나머지 원소들의 인덱스에는 영향을 미치지 않습니다.
| 마무리
프로젝트를 진행하며 리스트, 배열 등 컬렉션을 많이 사용하면서
이번에 발생한 에러에 대해 정리하였습니다.
분명 알고 있던 내용이지만 막상 프로젝트를 시작하고 정신없이 코딩하다 보니
신경을 쓰지 못했네요..
틀린 점이나 질문이 있으시면 댓글로 남겨주세요!
감사합니다 :)
'C#' 카테고리의 다른 글
C# List의 마지막 요소에 접근하는 3가지 방법 (0) | 2024.02.20 |
---|---|
C# 멀티스레드 동기화 : Monitor.Enter, Monitor.Exit (0) | 2024.02.19 |
C# 이미지의 2차원 배열을 순회하는 여러가지 방법 - 2 (2) | 2024.01.21 |
C# 이미지의 2차원 배열을 순회하는 여러가지 방법 - 1 (0) | 2024.01.19 |
C# Partial Class 이해 (0) | 2023.12.27 |