[2025_10_01]foreach문에서의 데이터 변경

2025. 10. 1. 22:05TIL

분명 배웠었고 기억하고 있다고 생각했었지만

막상 하다가 왜 안되지 라는 생각이 들었던 부분이다.

foreach문에서 데이터 변경

1. 문제 상황

  • List<Item>에서 RemoveAt()을 사용하려고 했으나 foreach문에서는 컬렉션 구조 변경이 불가능하다는 것을 다시 깨달음.
  • for문(역순)으로 변경하여 해결.

2. foreach의 3가지 제약사항

반복 변수 재할당 불가 (컴파일 에러)

 
csharp
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int num in numbers)
{
    num = num * 2;
}
//불가!

 반복 변수는 읽기 전용이라 컴파일 에러 발생

컬렉션 구조 변경 불가 (런타임 에러)

 
csharp
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (int num in numbers)
{
    numbers.Remove(num);     
    numbers.Add(10);         
    numbers.RemoveAt(0);     
}
//불가!

컬렉션의 Add/Remove/Clear 등은 불가능.

참조 타입의 내부 상태(속성,필드) 변경 가능

 
csharp
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Person[] people = new Person[] 
{ 
    new Person { Name = "김철수", Age = 20 }
};

foreach (Person person in people)
{
    person.Age += 1;              //가능
    person = new Person();        //불가
}

// for문에서는 가능:
for (int i = 0; i < people.Length; i++)
{
    people[i] = new Person();     //가능
}

3. 해결 방법

역순 for문 사용 (컬렉션에서 요소 제거 시 안전)

csharp
for (int i = equipItem.Count - 1; i >= 0; i--)
{
    equipItem.RemoveAt(i); 
}

역순을 사용하는 이유: 앞에서부터 제거하면 인덱스가 밀려서 요소를 건너뛸 수 있기 때문.


5. 결론

  • foreach = 읽기 전용 순회
  • 컬렉션 구조를 바꿔야 한다면 ->for문 사용
  • 참조 타입의 속성만 바꾼다면 ->foreach도 괜찮음
  • 반복 변수 재할당 X
  • 배열 요소 교체 X
  • 컬렉션 구조 변경 X
  • 참조 타입 내부 수정 O

'TIL' 카테고리의 다른 글

[2025_10_13]TextRpg 개발 회고  (0) 2025.10.13
[2025_10_02]Json-1  (0) 2025.10.02
[2025_09_29]클래스와 메서드 나누기  (0) 2025.09.29
[2025_09_26]for VS while,Array VS List  (0) 2025.09.26
[2025_09_25]UniRx  (0) 2025.09.25