[C#][Unity]List에서 원소 제거시 주의할 점

2023. 10. 23. 10:04·게임 관련/유니티
반응형

출처: https://penguinofdev.tistory.com/51

특정 조건에 맞는 LIst 안의 원소를 제거할 때, 별 생각없이 이렇게 할 때가 있다.

for(int i = 0; i < myList.Count; i++)
{
	if(조건이 참일 때)
		myList.Remove(myList[i]);
}

배열이 됐든 무엇이든 순회하는 과정에서 컨테이너의 내용이 변경되는 것은 위험한 작업일 수 있다.

 

위 코드도 중간에 어떤 값이 제거되면, list의 사이즈 역시 변경되어 잘못된 인덱스에 접근할 가능성이 매우 높다.

 

이럴 때는 다음과 같이 사용하자.

for(int i = myList.Count - 1; i >= 0; i--)
{
	if(조건이 참이면)
    		myList.Remove(myList[i]);
}

거꾸로 순회하면서 제거하면 안전하게 작업을 수행할 수 있다.

 

 

 

- Question

InvalidOperationException: The list was modified.

InvalidOperationException: The list was modified. Boo.Lang.List`1+c__Iterator6[UnityEngine.GameObject].MoveNext () Item.OnCollisionExit (UnityEngine.Collision collision) (at Assets/Item.js:73)

I simply want a list with item I currently collide with, so when I stop colliding they must be removed from the list:

EDIT: I changed my code but now it gives an index out of range exception

  1. function OnCollisionExit(collision : Collision) {
  2. for(var i = tegenstanders.Count; i> 0; i--)
  3. {
  4. item = tegenstanders[i];
  5. if(item.name == collision.gameObject.name)
  6. {
  7. tegenstanders.Remove(tegenstanders[i]);
  8. }
  9. }
  10. }

- Answer


This happens because you're removing items from the list at the same time as you are iterating through it. It's easier to explain if you convert the list to a non-enumerated for-loop instead:

  1. List<int> example = new List<int>();
  2. for (int i = 0; i < example.Count; i++)
  3. {
  4. if (something)
  5. example.Remove(example[i]); // Not safe to do
  6.  
  7. }

If you remove an item from the list while you're going through it, the for-loop's impression of the list's Count-property is no longer reliable, since the amount of elements in the list changed during execution of the loop. In addition, the enumeration is now messed up; example[i] now points to another item in the list, because the Remove-command has shifted all of the elements with a higher index down to keep them sequential in memory, so you would effectively skip an item if you kept iterating with it. That's why the enumerated version of the loop doesn't enjoy it very much when you modify the List in it.

To get around this issue, use a standard for-loop and iterate through the list backwards instead:

  1. List<int> example = new List<int>();
  2. for (int i = example.Count-1; i >= 0; i--)
  3. {
  4. if (something)
  5. example.Remove(example[i]); // Safe to do
  6. }

This is not a problem, because you're stopping iteration at 0, not at List.Count, and all of your indexes still point to the right elements just fine, because the elements get shifted down on Remove, and you've already iterated through those.

반응형
저작자표시 비영리

'게임 관련 > 유니티' 카테고리의 다른 글

React Native/IOS [IOS] 구글 애드몹 info.plist 설정 "The Google Mobile Ads SDK w  (0) 2023.12.03
Xcode Signing 설정했는데 Signing설정 안했다고 에러 날 경우  (0) 2023.12.02
유니티 - 프리팹 Load하는 3가지 방법  (0) 2023.10.11
유니티 Time.timeScale 프로퍼티 [유니티|Unity]  (0) 2023.04.19
C# 제네릭 (Generics) 타입 이란?  (0) 2022.10.23
'게임 관련/유니티' 카테고리의 다른 글
  • React Native/IOS [IOS] 구글 애드몹 info.plist 설정 "The Google Mobile Ads SDK w
  • Xcode Signing 설정했는데 Signing설정 안했다고 에러 날 경우
  • 유니티 - 프리팹 Load하는 3가지 방법
  • 유니티 Time.timeScale 프로퍼티 [유니티|Unity]
호레
호레
창업 / IT / 육아 / 일상 / 여행
    반응형
  • 호레
    Unique Life
    호레
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 법률
        • 기본
        • 개인정보보호법
        • 정보통신망법
        • 전자금융거래법
        • 전자금융감독규정
        • 신용정보법
        • 온라인투자연계금융업법
      • 창업
        • 외식업 관련
        • 임대업 관련
        • 유통업 관련
        • 세무 관련
        • 마케팅 관련
        • 기타 지식
        • 트렌드
        • Youtube
      • IT기술 관련
        • 모바일
        • 윈도우
        • 리눅스
        • MAC OS
        • 네트워크
        • 빅데이터 관련
        • A.I 인공지능
        • 파이썬_루비 등 언어
        • 쿠버네티스
        • 기타 기술
      • 퍼블릭 클라우드 관련
        • Azure
        • GCP
        • AWS
      • 정보보안 관련
        • QRadar
        • Splunk
        • System
        • Web
      • 기타
        • 세상 모든 정보
        • 서적
      • 게임 관련
        • 유니티
      • 부동산
      • 맛집 찾기
        • 강남역
        • 양재역
        • 판교역
        • ★★★★★
        • ★★★★
        • ★★★
        • ★★
        • ★
      • 결혼_육아 생활
        • 리얼후기
        • 일상
        • 육아
        • 사랑
        • Food
      • 영어
        • 스피킹
        • 문법
        • 팝송
        • 영화
      • K-컨텐츠
        • 드라마
        • 영화
        • 예능
      • 독서
      • 프로젝트 관련 조사
        • 시스템 구축
        • 로그 관련
        • 웹
        • APT
        • 모의 해킹
        • DB
        • 허니팟
        • 수리카타
        • 알고리즘
        • FDS
      • 기업별 구내 식당 평가
        • 한국관광공사
        • KT telecop
        • KT M&S
        • KT powertel
        • KT cs 연수원
        • 진에어
      • 대학 생활
        • 위드윈연구소
        • 진로 고민
        • 채용정보
        • 자동차
        • 주식
        • 악성코드
        • 게임 보안
      • 쉐어하우스
  • 블로그 메뉴

    • 홈
    • 게임 관련
    • IT 기술 관련
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    대통령
    수제버거
    판교역
    수제버거맛집
    돈까스
    AWS
    판교맛집
    무역전쟁
    점심
    판교
    이재곧죽습니다
    상호관세
    유니티
    마케팅
    런치
    쥬쥬랜드
    맛집
    수제버거존맛
    복리후생
    보안가이드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
호레
[C#][Unity]List에서 원소 제거시 주의할 점
상단으로

티스토리툴바