C# 에서 foreach() 문은 리스트나 배열 같은 컬렉션을 순회할 때 자주 사용됩니다.
코드가 간결하고 가독성도 좋기 때문에 선호되지만, 한 가지 중요한 제한이 있습니다.
foreach() 는 읽기 전용
foreach (var pb in listPB)
{
if (IsCollision(pb, ball))
{
// 순회 중 컬렉션 변경 -> 예외 발생!!
listPB.Remove(pb);
break;
}
}
겉보기에는 문제가 없어 보이지만, 이 코드는 실행 시 InvalidOperationException 예외를 발생시킵니다.
foreach()는 내부적으로 열거자(Enumerator) 를 사용하기 때문에, 순회 중 컬렉션이 변경되면 예외를 던지게 되어 있습니다. break 로 바로 빠져나온다 해도 이미 순회 중에 Remove()가 실행되었기 때문에 위험한 코드입니다.
컬렉션을 수정하려면 for() 문으로 순회
따라서 컬렉션을 수정해야 하는 경우는 반드시 for() 문을 사용해야 합니다.
for( int i = 0; i < listPB.Count; i++)
{
if (IsCollision(listPB[i], ball))
{
listPB.RemoveAt(i);
break;
}
}
이 방식은 안전하게 작동하지만, 한 가지 주의할 점이 있습니다.
RemoveAt()을 하면 리스트의 뒤 요소들이 한 칸씩 앞으로 당겨지기 때문에, 인덱스를 증가시키는 구조에서는 다음 요소를 건너뛸 수 있습니다.
for() 문으로 순회 중, 여러 개를 삭제해야 한다면, 역방향으로
for (int i = listPB.Count - 1; i >= 0; i--)
{
if (IsCollision(listPB[i], ball))
{
listPB.RemoveAt(i);
}
}
위와 같이 끝에서부터 역방향으로 순회하면, 삭제 후 요소가 앞으로 당겨지더라도 이미 지난 인덱스들이므로 영향을 받지 않습니다.
정리
• 순회 중 삭제가 없다면 : foreach()
• 순회 중 1개를 삭제해야 한다면 : for() 순방향 또는 역방향
• 순회 중 2개 이상을 삭제해야 한다면 : for() 역방향
'C#' 카테고리의 다른 글
bool = 조건식 과 삼항 연산자 (0) | 2025.06.29 |
---|---|
C# 의 Interface 기초부터 활용까지 (1) | 2025.06.26 |
C#의 is 와 as 키워드 (#02) (0) | 2025.06.26 |
C#의 is 와 as 키워드 (#01) (0) | 2025.06.26 |
C# 의 상속이 C++ 과 다른 점 (0) | 2025.06.25 |