C#/배열

[C#]배열 복사하는 방법

DevStory 2022. 8. 23.

배열 복사하는 방법

C#의 배열은 참조 타입이므로 실제 데이터는 Heap 영역에 생성되고 변수는 Stack 영역에 생성됩니다.

 

Stack 영역에 생성된 변수는 참조 값(Heap 영역에 생성된 실제 데이터의 위치)을 통해 배열의 데이터를 접근합니다. 만약, 참조 값을 다른 변수에 할당하는 경우 두 개 이상의 변수가 Heap 영역에 존재하는 배열의 데이터를 공유하게 됩니다.

 

다음 예제는 배열 변수를 다른 변수에 할당 후 값을 변경했을 때, 원본 데이터가 보존되지 않는 문제를 보여줍니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 5, 10, 15, 20 };
    int[] copyArray = intArray;

    Console.WriteLine("[변경 전]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));

    copyArray[0] = 10;

    Console.WriteLine("\n[변경 후]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));
  }
}

[실행 결과]

[변경 전]
intArray: 5, 10, 15, 20
copyArray: 5, 10, 15, 20

[변경 후]
intArray: 10, 10, 15, 20
copyArray: 10, 10, 15, 20

따라서, 배열 변수를 다른 변수에 할당하는 방법은 원본 데이터가 변경될 수 있으므로 배열을 복사하는 방법으로 적절하지 않습니다.

 

이번 포스팅은 배열을 복사할 수 있는 몇 가지 방법을 소개하며, 아래 방법들을 통해 원본 데이터를 보존합니다.


방법 1. 반복문

가장 심플한 방법으로 반복문을 사용하여 배열을 복사할 수 있습니다.

 

[복사 방법]

순서 1. 원본 배열의 요소 개수를 새로운 배열의 크기로 설정합니다.

순서 2. 반복문을 사용하여 원본 배열의 값을 새로운 배열에 할당합니다.

 

다음 예제는 for문을 사용하여 배열을 복사합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 5, 10, 15, 20 };
    int[] copyArray = new int[intArray.Length];

    Console.WriteLine("[복사 전]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));

    for (int index = 0; index < intArray.Length; index++)
    {
      copyArray[index] = intArray[index];
    }

    Console.WriteLine("\n[복사 후]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));
  }
}

[실행 결과]

[복사 전]
intArray: 5, 10, 15, 20
copyArray: 0, 0, 0, 0

[복사 후]
intArray: 5, 10, 15, 20
copyArray: 5, 10, 15, 20

방법 2. Array 클래스의 Clone 메서드

두 번째 방법으로 Array 클래스의 Clone() 메서드를 사용하여 배열을 복제할 수 있습니다.

 

Clone() 메서드는 원본 배열의 모든 요소에 대해 얕은 복사를 수행하고 새로운 배열을 반환합니다. Clone() 메서드를 사용하여 배열을 복사하는 경우 타입 캐스팅이 필요합니다.

 

다음 예제는 Clone() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 50으로 변경합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 5, 10, 15, 20 };
    int[] copyArray = (int[])intArray.Clone();

    Console.WriteLine("[복사 후]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));

    copyArray[0] = 50;

    Console.WriteLine("\n[copyArray의 0번째 위치 값을 50으로 변경]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));
  }
}

[실행 결과]

[복사 후]
intArray: 5, 10, 15, 20
copyArray: 5, 10, 15, 20

[copyArray의 0번째 위치 값을 50으로 변경]
intArray: 5, 10, 15, 20
copyArray: 50, 10, 15, 20

방법 3. Array 클래스의 CopyTo 메서드

세 번째 방법으로 Array 클래스의 CopyTo() 메서드를 사용하여 배열을 복사할 수 있습니다. 

 

[복사 방법]

순서 1. 원본 배열의 요소 개수를 새로운 배열의 크기로 설정합니다.

순서 2. 원본 배열에서 CopyTo() 메서드를 호출하고 첫 번째 매개변수로 새로운 배열을 전달하고 두 번째 매개변수로 0을 전달합니다. 원본 배열의 0번째 위치부터 값이 복사됩니다.

 

다음 예제는 CopyTo() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 50으로 변경합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 5, 10, 15, 20 };
    int[] copyArray = new int[intArray.Length];

    intArray.CopyTo(copyArray, 0);

    Console.WriteLine("[복사 후]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));

    copyArray[0] = 50;

    Console.WriteLine("\n[copyArray의 0번째 위치 값을 50으로 변경]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));
  }
}

[실행 결과]

[복사 후]
intArray: 5, 10, 15, 20
copyArray: 5, 10, 15, 20

[copyArray의 0번째 위치 값을 50으로 변경]
intArray: 5, 10, 15, 20
copyArray: 50, 10, 15, 20

방법 4. Array 클래스의 ConstrainedCopy 메서드

네 번째 방법으로 Array 클래스의 ConstrainedCopy() 메서드를 사용하여 배열을 복사할 수 있습니다.

public static void ConstrainedCopy(
  Array sourceArray, int sourceIndex, 
  Array destinationArray, int destinationIndex, 
  int length);

Array sourceArray

- 복사하고자 하는 소스로 원본 배열입니다.

 

int sourceIndex

- 복사하고자 하는 소스(Object src)에서 데이터를 읽을 시작 위치입니다.

 

Array destinationArray

- 원본 배열에서 복사한 데이터를 할당하려는 배열입니다.

- 즉, 새로운 배열입니다.

 

int destinationIndex

- 새로운 배열(Object dest)의 시작 위치입니다.

- 0으로 설정하는 경우 복사한 데이터가 새로운 배열의 인덱스 0부터 할당됩니다.

- 3으로 설정하는 경우 복사한 데이터가 새로운 배열의 인덱스 3부터 할당됩니다.

 

int length

- 원본 배열에서 복사되는 데이터 개수입니다.

 

[복사 방법]

순서 1. 원본 배열의 요소 개수를 새로운 배열의 크기로 설정합니다.

순서 2. Array 클래스의 ConstrainedCopy() 메서드를 호출하고 원본 배열, 새로운 배열, 복사 시작 위치, 복사하려는 데이터 개수를 매개변수로 전달합니다.

 

다음 예제는 ConstrainedCopy() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 50으로 변경합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 5, 10, 15, 20 };
    int[] copyArray = new int[intArray.Length];

    Array.ConstrainedCopy(intArray, 0, copyArray, 0, intArray.Length);

    Console.WriteLine("[복사 후]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));

    copyArray[0] = 50;

    Console.WriteLine("\n[copyArray의 0번째 위치 값을 50으로 변경]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));
  }
}

[실행 결과]

[복사 후]
intArray: 5, 10, 15, 20
copyArray: 5, 10, 15, 20

[copyArray의 0번째 위치 값을 50으로 변경]
intArray: 5, 10, 15, 20
copyArray: 50, 10, 15, 20

방법 5. LINQ의 ToArray 메서드

마지막 방법으로 LINQ에서 제공하는 ToArray() 메서드를 사용하여 배열을 복사할 수 있습니다.

 

먼저, LINQ에서 제공하는 기능을 사용하기 위해 다음 네임스페이스를 추가합니다.

using System.Linq;

다음 예제는 ToArray() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 50으로 변경합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 5, 10, 15, 20 };
    int[] copyArray = intArray.ToArray();

    Console.WriteLine("[복사 후]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));

    copyArray[0] = 50;

    Console.WriteLine("\n[copyArray의 0번째 위치 값을 50으로 변경]");
    Console.WriteLine("intArray: " + string.Join(", ", intArray));
    Console.WriteLine("copyArray: " + string.Join(", ", copyArray));
  }
}

[실행 결과]

[복사 후]
intArray: 5, 10, 15, 20
copyArray: 5, 10, 15, 20

[copyArray의 0번째 위치 값을 50으로 변경]
intArray: 5, 10, 15, 20
copyArray: 50, 10, 15, 20
반응형

댓글