내맘대로 공부기록.

[ STUDY ]

C++ vector 타입과 조금 다른 C# List 타입 변수의 사용.

fwanggus 2022. 2. 13. 16:39
반응형

두 변수 타입 모두 어레이 형태로 사용할 수 있습니다.

어레이의 요소 타입을 괄호(<>) 안에 선언 후 사용하는 부분은 같습니다.

 

  C# C++
형태 List<[요소의 타입]>() vector<[요소의 타입]>

 

Clear 메서드 사용의 차이점. 

선언한 List(C#), vector(C++) 변수의 요소를 모두 삭제하기 위해 Clear 메서드를 사용할 수 있습니다. 두 언어에서 메서드를 콜 하는 방법 또한 같습니다.

 

/* arrVar : 각 언어에서 사용하는 List, vector 타입의 변수명 */
// C#
arrVar.Clear();
// C++ ; 소문자 c
arrVar.clear()

 

다른 점이라고 할까요 ? C++ 언어와 비교해서 작업했던 썰을 적어봅니다.

C++에서 이미지 전처리 로직을 짜고, C# 윈도우 프로그램을 작성하기 위해 코드를 전환하는 중이었습니다.

C#의 경우 Clear 메서드를 호출하는 순간, 선언된 서로 다른 List 타입의 변수가 모두 Clear 되는 현상이 있더라구요 ?

 

여기저기 찾아보니, C#의 List 변수는 클래스이고, 서로 다른 리스트에 리스트의 요소로써 할당하는 경우, Reference 형태로 할당되기 때문에 Clear를 콜 하는 순간, 참조하고 있는 요소의 parent, child 변수가 모두 Clear 되는? 느낌적인 느낌입니다.

 

이 링크를 참고했습니다.

 

Why clearing a list clears another list? - Unity Answers

 

answers.unity.com

 

의도했던 부분은 서로 다른 리스트 변수 A, B를 가지고 있는 상태에서 루프 작업을 수행합니다.

1차원 리스트 변수 A는 필요한 단위 개수의 정보를 처리, 저장 후 또 다른 2차원 리스트 변수 B의 한 요소로써 추가, 전달해주도록 작성했습니다. 

그리고, 다음 루프를 수행하기 위해 1차원 리스트의 요소를 모두 비워주기로 했습니다. 여기서 Clear 메서드를 호출했습니다. 당연히 1차원 리스트만 Clear 될 줄 알았는데, 2차원 리스트 B도 같이 Clear가 돼버렸습니다.

 

 

그렇다면, 이 현상을 해결하기 위해 Reference 형태로 전달된 값을 Value 형태로 전달해주면 문제가 없을 것 같다는 단순한 생각을 해봤습니다. VB.NET 에서 변수를 ByRef 또는 ByVal 형태로 선언할 수 있는 점이 생각나더라구요.

하지만, 참조 형태의 Add 메서드 같은 방법은 찾을 수 없었습니다. 검색 스킬을 더 연마해야 할지...

 

아무튼 또 다른 방법으로 AddRange 메서드를 이용하는 방법이 있어 테스트를 해봤습니다. 문제없이 작동합니다.

 

List<T>.AddRange(IEnumerable<T>) Method (System.Collections.Generic)

Adds the elements of the specified collection to the end of the List<T>.

docs.microsoft.com

 

 

 

 

Add 메서드로 List를 사용한 경우

		...
		List<int> lst1stOrd = new List<int>();
		List<List<int>> lst2ndOrd = new List<List<int>>();

		/* 1st order 리스트에 값 추가 */
		lst1stOrd.Add(1);
		lst1stOrd.Add(50);

		/* 1st order 요소를 2nd order 리스트에 추가 */
		lst2ndOrd.Add(lst1stOrd);

		// initializing... 여기서 2nd order 리스트도 초기화 되버림.
		lst1stOrd.Clear();
		...

 

AddRange 메소드로 List를 사용한 경우

  1. 1차원 리스트 A를 B와 같은 형태의 2차원 리스트를 선언
  2. AddRange 메서드 콜, B 의 마지막 인덱스에 추가
  3. A 리스트의 Clear 메소드 콜. (B 리스트는 초기화되지 않음.)
            ...
            List<List<int>> lst2ndOrdA = new List<List<int>>();
            List<List<int>> lst2ndOrdB = new List<List<int>>();

            /* 2nd order A 리스트에 값 추가 */
            lst2ndOrdA.Add(new List<int> { 1, 50 });
            lst2ndOrdA.Add(new List<int> { 9, 8, 5, 3 });


            /* A 리스트 요소를 B 리스트에 추가 */
            lst2ndOrdB.AddRange(lst2ndOrdA);
            // initializing... B 리스트는 초기화 되지 않음.
            lst2ndOrdA.Clear();

            /* 2nd order A 리스트에 값 추가 */
            lst2ndOrdA.Add(new List<int> { 451, 59 });
            lst2ndOrdA.Add(new List<int> { 2 });

            /* A 리스트 요소를 B 리스트에 추가 */
            lst2ndOrdB.AddRange(lst2ndOrdA);
            // initializing... B 리스트는 초기화 되지 않음.
            lst2ndOrdA.Clear();
            ...

 

디버그, 콘솔 출력 결과 

 

이 방법으로 이미지 전처리 작업에 적용해보겠습니다. 

반응형