언어/C#
C#에서 배열을 부분 참조하는 방법
alpacadabra
2022. 12. 29. 01:48
소켓 프로그래밍을 공부하다 알게 된 내용인데,
과연 다른 곳에 써먹을 일이 있을까 싶지만, 아무튼...
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