< 인덱서에서의 유효성 검증과 계산>

인덱서를 사용하면 내부 데이터에 직접 접근하는 것이 아니라 메소드를 통해 접근하므로 유효성 검사나 추가적인 계산을 수행할 수 있다. 예를 들어, 내부 배열에 접근하는 인덱서에 유효한 인덱스만 허용하도록 유효성 검사를 추가할 수 있다.

public T this[int i]
{
    get
    {
        if (i >= 0 && i < arr.Length)
        {
            return arr[i];
        }
        else
        {
            throw new IndexOutOfRangeException();
        }
    }
    set
    {
        if (i >= 0 && i < arr.Length)
        {
            arr[i] = value;
        }
        else
        {
            throw new IndexOutOfRangeException();
        }
    }
}

 

이 코드는 인덱스가 배열의 범위를 벗어나지 않는지 확인하고, 그렇지 않은 경우 IndexOutOfRangeException을 발생시킨다.

< 인덱서와 상속 >

인덱서는 virtual, abstract 또는 override 키워드와 함께 사용될 수 있다. 이를 통해 인덱서의 동작을 하위 클래스에서 변경하거나 확장할 수 있다. 예를 들어, 기본 클래스에서 virtual 키워드를 사용해 인덱서를 정의하고, 하위 클래스에서 override 키워드를 사용해 그 동작을 변경할 수 있다.

public virtual T this[int i]
{
    get { /* 기본 구현 */ }
    set { /* 기본 구현 */ }
}

// 하위 클래스에서
public override T this[int i]
{
    get { /* 변경된 구현 */ }
    set { /* 변경된 구현 */ }
}

 

이를 통해 클래스 계층에서 인덱서의 동작을 더욱 유연하게 관리할 수 있다.

< 인터페이스와 인덱서 >

인덱서는 인터페이스에도 포함될 수 있다. 이를 통해 특정 클래스가 반드시 구현해야 하는 인덱서를 지정할 수 있다.

public interface ISampleCollection<T>
{
    T this[int i] { get; set; }
}
// 이 인터페이스를 구현하는 클래스에서
public class SampleCollection<T> : ISampleCollection<T>
{
    // 인터페이스의 인덱서 구현
    public T this[int i]
    {
        get { /* 구현 */ }
        set { /* 구현 */ }
    }
}


이를 통해 클래스 간의 계약을 정의하고 코드의 일관성을 유지할 수 있다.

< 읽기 전용 또는 읽기/쓰기용 인덱서 >

인덱서는 get 접근자만을 포함하여 읽기 전용으로 만들 수 있다. 반대로 get과 set 접근자를 모두 포함하여 읽기/쓰기용으로 만들 수도 있다. 이를 통해 클래스의 내부 데이터에 대한 접근을 더욱 세밀하게 제어할 수 있다.

// 읽기 전용 인덱서
public T this[int i]
{
    get { /* 구현 */ }
}

// 읽기/쓰기용 인덱서
public T this[int i]
{
    get { /* 구현 */ }
    set { /* 구현 */ }
}


이를 통해 클래스의 내부 데이터를 보호하고 외부에서의 변경을 제어할 수 있다.

< 데이터 바인딩과 인덱서 >

정수를 매개변수로 받는 1차원 인덱서는 데이터 바인딩에 유용하게 사용될 수 있다. 데이터 바인딩이란 데이터를 UI 요소에 연결하는 프로세스를 의미한다. 이런 방식으로, 인덱서를 통해 각 항목에 접근하면서 데이터를 UI 요소에 연결할 수 있다.

< 맵 정의와 인덱서 >

또한, 정수 이외의 매개 변수를 받는 인덱서는 맵(Map)을 정의하는데 유용하다. 키-값 쌍을 저장하는 자료구조인 맵에 접근하기 위해 인덱서를 사용할 수 있다. 예를 들어, 문자열 키와 값을 갖는 맵을 정의하려면 다음과 같이 인덱서를 사용할 수 있다.

public T this[string key]
{
    get { /* key에 해당하는 값을 반환 */ }
    set { /* key에 해당하는 값을 설정 */ }
}

 

이렇게 해서 인덱서는 클래스가 배열처럼 동작하게 하고, 동시에 캡슐화를 유지하면서 복잡한 동작을 가능하게 할 수 있다.


+ Recent posts