프로그래밍/C#

[C#] List<T>를 이용할때, 같은 값이 계속해서 출력되는 이유?

gameObject 2023. 6. 20. 00:44
728x90

핵심은 List는 값을 참조해서 가져온다는 것이다.

참조하는 본체를 하나로만 두고 본체의 값을 변경한다면, List는 0~List.Count 값까지 전부 똑같이 변하게 된다.

 

아래 예시이다.

List<string[]> 리스트에 스트링배열을 넣어서 선언을 해주었는데

string[] cardMemory라는 변수로 while을 돌려서 List에 계속 값을 넣어주었다.

 

중간에 프린트를 찍어보았을때는 분명 값이 랜덤으로 들어간것으로 확인이 되었었는데

그런데 마지막에 출력시에는 같은값이 14개가 프린트가 되었다.

 

나는 랜덤값으로 계속 cardMemory를 초기화 해준것으로 생각했으나 그것이 아니었다.

 

cardMemory를 초기화 해주기 위해서는 new를 이용하여 새로 할당해주어야 한다.

 if (!isDuplicate)
                {
                    cardDeck.Add(cardMemory);
                    cardMemory = new string[2];
                }

이 부분이 핵심이다.

 

그렇게 하지 않는다면 List는 값을 변수에서 참조하여 가져오기 때문에 0번부터 14번 인덱스까지 cardMemory의 값이 변경될때마다

List에 할당한 값 전체가 변경되게 되어 연속해서 똑같은 값이 출력되는 오류를 범할 수 있다.

 

아래는 오류코드 이다.

//using System;

//namespace MyApp
//{
//    internal class Program
//    {
//        static void Main(string[] args)
//        {
//            string[] cardNumber = new string[13] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
//            string[] cardMark = new string[4] { "♠", "♥", "♣", "◆" };
//            string[] cardMemory = new string[2];


//            Random rand = new Random();

//            List<string[]> cardDeck = new List<string[]>();

//            int random1 = default;
//            int random2 = default;

//            //cardMemory[0] = cardNumber[1];
//            //cardMemory[1] = cardMark[0];

//            //cardDeck.Add(cardMemory);
//            //cardDeck.Add(cardMemory);
//            //cardDeck.Add(cardMemory);
//            //cardDeck.Add(cardMemory);

//            //Console.WriteLine(cardDeck[3][0]);

//            while (true)
//            {
//                int j = 0;
//                int k = 0;

//                random1 = rand.Next(0, 13);
//                random2 = rand.Next(0, 4);

//                cardMemory = new string[2];

//                cardMemory[0] = cardNumber[random1];
//                cardMemory[1] = cardMark[random2];

//                ////중복조건
//                //cardDeck.Add(cardMemory);

//                //while (true)
//                //{ 
//                //    if((cardDeck[k][0] == cardMemory[0]) && (cardDeck[k][1] == cardMemory[1]))
//                //    {
//                //        random1 = rand.Next(0, 13);
//                //        random2 = rand.Next(0, 4);

//                //        cardMemory[0] = cardNumber[random1];
//                //        cardMemory[1] = cardMark[random2];
//                //    }
//                //    else if(cardDeck.Count == k)
//                //    {
//                //        break;
//                //    }
//                //    k++;

//                //}
//                if (cardDeck.Count == 14)
//                {
//                    break;
//                }



//                for (int i = 0; i < cardDeck.Count + 1; i++)
//                {
//                    if (cardDeck.Count == 14)
//                    {
//                        break;
//                    }

//                    if (j == cardDeck.Count)
//                    {
//                        cardDeck.Add(cardMemory);
//                        //Console.WriteLine(cardMemory[0] + cardMemory[1]);

//                        break;
//                    }



//                    //if ((cardDeck[i][0] != cardMemory[0]) || (cardDeck[i][1] != cardMemory[1]))
//                    //{
//                    //    j++;
//                    //}
//                    //else if (cardDeck[i] == cardMemory)
//                    //{
//                    //    break;
//                    //}
//                    j++;

//                    //중복조건
//                    if ((cardDeck[i][0] == cardMemory[0]) && (cardDeck[i][1] == cardMemory[1]))
//                    {



//                    }
//                }
//            }

//            //Console.WriteLine(cardDeck[5][0] + cardDeck[5][1]);
//            //Console.WriteLine();


//            for (int i = 0; i < cardDeck.Count; i++)
//            {
//                Console.WriteLine(cardDeck[i][0] + cardDeck[i][1]);
//            }

//        }//Main
//    }//class
//}//namespace

 

 

수정한 코드

using System;
using System.Collections.Generic;

namespace MyApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string[] cardNumber = new string[13] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
            string[] cardMark = new string[4] { "♠", "♥", "♣", "◆" };
            string[] cardMemory = new string[2];

            Random rand = new Random();
            List<string[]> cardDeck = new List<string[]>();

            while (cardDeck.Count < 14)
            {
                int random1 = rand.Next(0, 13);
                int random2 = rand.Next(0, 4);

                cardMemory[0] = cardNumber[random1];
                cardMemory[1] = cardMark[random2];

                bool isDuplicate = false;
                foreach (string[] card in cardDeck)
                {
                    if (card[0] == cardMemory[0] && card[1] == cardMemory[1])
                    {
                        isDuplicate = true;
                        break;
                    }
                }

                if (!isDuplicate)
                {
                    cardDeck.Add(cardMemory);
                    cardMemory = new string[2];
                }
            }

            foreach (string[] card in cardDeck)
            {
                Console.WriteLine(card[0] + card[1]);
            }
        }
    }
}

 

728x90