<개인공부>/[C#]

[C#] 인덱서 객체(인스턴스)를 배열 처럼 사용해보자

BlockDMask 2022. 9. 4. 20:00
반응형

안녕하세요 BlockDMask입니다.
오늘은 C# indexer에 대해서 알아보려고 합니다.

<목차>
1. C# indexer 란? (인덱서 사용 전 후 비교)
2. C# indexer 예시

*해당 문서에서는 객체와 인스턴스를 거의 동일시해서 언어를 사용했습니다.
객체 : 클래스의 타입으로 선언 되었을 때
인스턴스 : 실제 객체가 메모리에 할당되어 사용될 때

 

1. C# 인덱서란?

1-1) 인덱서 사용법 및 설명

우리가 데이터를 편리하게 다루려고 배열을 사용하고 있지 않나요?
배열 arr 이 존재한다고 했을 때 배열의 N번째 요소에 접근하기 위해서 우리는 arr[N] 을 사용하잖아요? (N은 0부터 시작)
이렇게 배열을 통해서 쉽게 접근하는 유용한 문법을 "클래스 내부에 있는 배열에 한 번에 접근하고 싶을 때" 사용하는 문법이 인덱서라는 문법입니다.

정리를 하면
특정 클래스 내부(객체 내부에)에 있는 배열을, 객체 배열처럼 손쉽게 접근할 수 있게 하는 문법
문법에 사용되는 주 키워드는this입니다.

public 반환형 this[int idx] 로 만들어 주고 내부에 get, set을 만들어 주면 끝입니다. 간단하죠?

class 클래스 이름
{
    private 타입 배열 = new 배열타입[길이];
    
    public 반환형 this[int idx]
    {
        get { return 배열[idx]; }
        set { 배열[idx] = value; }
    }
}

이제 실제로 사용할때는 그럼 어떻게 사용하는가 하면

var 인스턴스 = new 클래스();

인스턴스[0] = 값;
var a = 인스턴스[0];

이런식으로 클래스의 인스턴스(instance)에 [] 대괄호를 통해서
손쉽게 바로 접근, 값 할당이 가능하게 됩니다.

 

1-2) 인덱서 사용 전 후 비교

아래 예제를 먼저 살펴보겠습니다. 
indexer를 사용하지 않았을 때
class Student라는 클래스가 있다고 하면 클래스 내부에 grades라는 int 타입의 배열을 만들어 둡니다.
실제로 private로 변수라서 해당 변수에 접근하기 위해서는 따로 setter, getter를 만들어주어야 합니다.
그리고 클래스 인스턴스를 통해서 멤버함수(메서드)를 호출해 주는 방식으로 배열에 접근을 해야 합니다.

class Student
{
    private int[] grades = new int[100];

    public int GetGrade(int idx) => grades[idx];
    public int SetGrade(int idx, int grade) => grades[idx] = grade;
}


class Program
{ 
    static void Main()
    {
        var student = new Student();

        // set 
        student.SetGrade(0, 123);
        student.SetGrade(1, 456);

        // get
        Console.WriteLine($"student.GetGrade(0) : {student.GetGrade(0)}");
        Console.WriteLine($"student.GetGrade(1) : {student.GetGrade(1)}");
    }
}

C# indexer 사용 안한 예제

 

그런데 아래와 같이 인덱서를 이용하게 되면, 쉽게 클래스의 인스턴스(객체)를 만들어서 그 인스턴스로 바로 배열에 접근할 수가 있습니다.

using System;

class Student
{
    private int[] grades = new int[100];

	// 인덱서 문법
    public int this[int idx]
    {
        get { return grades[idx]; }
        set { grades[idx] = value; }
    }
}


class Program
{ 
    static void Main()
    {
        var student = new Student();

        // set 
        student[0] = 20;
        student[1] = 10;

        // get
        Console.WriteLine($"student[0] : {student[0]}");
        Console.WriteLine($"student[1] : {student[1]}");
    }
}

C# 인덱서 사용 예제

 

 

2. C# 인덱서 예제

제네릭을 이용하면 어떤 타입이든 사용할 수 있겠죠?

class Student<T>
{
    private T[] grades = new T[100];

    public T this[int idx]
    {
        get { return grades[idx]; }
        set { grades[idx] = value; }
    }
}


class Program
{
    static void Main()
    {
        // (1) int 타입
        var student1 = new Student<int>();

        // set 
        student1[0] = 20;
        student1[1] = 10;

        // get
        Console.WriteLine("Student<int>");
        Console.WriteLine($"student1[0] : {student1[0]}");
        Console.WriteLine($"student1[1] : {student1[1]}");

        // (2) string 타입
        var student2 = new Student<string>();

        // set 
        student2[0] = "BlockDMask";
        student2[1] = "Blog";

        // get
        Console.WriteLine("\n\nStudent<string>");
        Console.WriteLine($"student2[0] : {student2[0]}");
        Console.WriteLine($"student2[1] : {student2[1]}");
    }
}

이렇게 제네릭을 사용하면 더 편리하게 클래스 내부 다양한 배열에 손쉽게 접근할 수 있습니다.

C# 인덱서 제네릭 예제

 

 

감사합니다. 이렇게 오늘은 C# 인덱서 문법에 대해서 알아보았습니다.
클래스 내부에서 배열을 사용하고 있고, 클래스 객체(인스턴스)를 통해서 쉽게 접근하고자 한다면 인덱서 문법을 이용해 보세요!

참고 문서 : https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/indexers/

반응형