본문 바로가기
언어/C#

C#에서 배열을 부분 참조하는 방법

by alpacadabra 2022. 12. 29.

소켓 프로그래밍을 공부하다 알게 된 내용인데,

과연 다른 곳에 써먹을 일이 있을까 싶지만, 아무튼...

C#의 배열은 기본적으로 참조 타입이므로 아래와 같은 작업이 가능하다.

 


class Program
{
    static void Main()
    {
        int[] arr1 = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[] arr2 = arr1;

        Console.WriteLine($"{arr1[0]} {arr2[0]}");
        arr1[0] = 123;
        Console.WriteLine($"{arr1[0]} {arr2[0]}");
    }
}

결과


 

위 코드처럼 arr2 arr1 을 대입하면 두 변수는 동일한 배열을 참조하게 되는 것을 알 수 있다.

(참고로 C++에서는 복사 생성자가 호출된다!)

그러나, 배열을 일부분만 참조하고 싶다면 얘기는 달라지는데...

 


class Program
{
    static void Main()
    {
        int[] arr1 = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[] arr2 = arr1[0..3];

        Console.WriteLine($"{arr1[0]} {arr2[0]}");
        arr1[0] = 123;
        Console.WriteLine($"{arr1[0]} {arr2[0]}");
    }
}

결과


 

단순히 arr1 을 슬라이싱하여 arr2 에 대입하면, 이는 참조 범위를 조정하는 것이 아니라 실제 값을 복사하여 저장하는 것이 된다.

만약 참조를 원한다면, 슬라이싱이 아닌 ArraySegment<T> 구조체를 사용해야 한다. 

 


class Program
{
    static void Main()
    {
        int[] arr1 = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        ArraySegment<int> arr2 = new(arr1, 0, 3);

        Console.WriteLine($"{arr1[0]} {arr2[0]}");
        arr1[0] = 123;
        Console.WriteLine($"{arr1[0]} {arr2[0]}");

        //Index out of range
        Console.WriteLine(arr2[3]);
    }
}

결과


 

ArraySegment 생성자의 첫 인자는 참조하고자 하는 배열이고, 두번째 인자는 오프셋(시작 위치), 세번째 인자는 크기이다.

위 코드에서는 arr1 의 0번째 원소부터 3개, 즉 2번째 원소까지 arr2 가 참조하도록 하였다.

따라서, 0번째 원소는 정상적으로 참조가 가능했지만, 3번째 원소는 arr2 의 범위를 벗어나는 것을 확인할 수 있다.

 

 

 

ArraySegment<T> 구조체 (System)

1차원 배열의 섹션을 구분합니다.

learn.microsoft.com

댓글