C#

[C#] 인덱서

Prooni 2024. 10. 7. 15:13

안녕하세요!

 오늘은 C#의 인덱서에 대해 공부해요~

 

인덱서는 인덱스를 이용해서 객체 내의 데이터에 접근하게 해줘요!

선언 형태는 아래와 같습니다.

 

class 클래스명
{
	한정자 인덱서_형식 this[형식 index]
    {
    	get
        {
        	//index를 이용하여 내부 데이터 반환
        }
        set
        {
        	//index를 이용하여 내부 데이터 저장
        }
    }
}

 

프로퍼티와 비슷하지만

프로퍼티는 이름을 통해 객체 내의 데이터에 접근하게 해주고

인덱서는 인덱스를 통해 객체의 데이터에 접근하게 해준답니다.

 

예제코드 첨부할게요.

class MyList
{
    private int[] array;

    public MyList()
    {
        array = new int[3];
    }

    public int this[int index]
    {
        get
        {
            return array[index];
        }
        set
        {
            if(index >= array.Length)
            {
                Array.Resize<int>(ref array, index + 1);
                Console.WriteLine($"Array Resized : {array.Length}");
            }

            array[index] = value;
        }
    }

    public int Length
    {
        get
        {
            return array.Length;
        }
    }
}

class MainApp
{
    static void Main(string[] args)
    {
        MyList list = new MyList();
        for(int i = 0; i < 5; i++)
        {
            list[i] = i;
        }

        for(int i = 0; i < list.Length; i++)
        {
            Console.WriteLine(list[i]);
        }
    }
}

 

마지막으로 foreach 사용이 가능한 객체를 만드는 법에 대해 알아볼게요!

foreach는 배열이나 리스트와 같은 컬렉션에서만 사용가능해요.

 

따라서 우리가 직접 만드는 클래스의 객체에 대해 foreach를 사용하기 위해서는

해당 클래스가 IEnumerable을 상속받아야만 해요!

 

IEnumerable이 인터페이스이므로 내부 메소드를 반드시 구현해야하는데

메소드가 딱 하나에요!

IEnumerator GetEnumerator() //IEnumerator 형식의 객체를 반환

 

그런데 여기서 해당 메소드를 구현하지 않고 yield문을 이용해도 된답니다!

yield문을 사용하면 컴파일러가 자동으로 해당 인터페이스를 구현한 클래스를 생성해줘요~

 

예시코드 첨부할게요.

class MyEnumerator
{
    int[] numbers = { 1, 2, 3, 4 };

    public IEnumerator GetEnumerator()
    {
        yield return numbers[0];
        yield return numbers[1];
        yield return numbers[2];
        yield break;
        yield return numbers[3];
    }
}

class MainApp
{
    static void Main(string[] args)
    {
        var obj = new MyEnumerator();
        foreach(int i in obj)
        {
            Console.WriteLine(i);
        }
    }
}

 

위 코드에서는 yield문을 통해 IEnumerable을 상속하는 클래스가 자동으로 구현되었지만

yield를 쓰지 않고도 해볼게요!

 

그럼 직접 IEnumerable 내부의 GetEnumerator() 메소드를 구현해야겠죠?

GetEnumerator()는 IEnumerator 인터페이스를 상속하는 객체를 반환하면 됩니다.

아래 코드에서 MyList라는 클래스를 선언하고

이 클래스가 IEnumerable과 IEnumerator를 모두 상속 받도록 할게요!

 그럼 GetEnumerator() 메소드 구현시 본인인 this를 반환하면 되겠죠?ㅎㅎ

 

그럼 예시코드 첨부할게요.

class MyList : IEnumerable, IEnumerator
{
    private int[] array;
    int position = -1;

    public MyList()
    {
        array = new int[3];
    }

    public int this[int index]
    {
        get
        {
            return array[index];
        }
        set
        {
            if(index >= array.Length)
            {
                Array.Resize<int>(ref array, index + 1);
                Console.WriteLine($"Array Resized : {array.Length}");
            }

            array[index] = value;
        }
    }

    //IEnumerator 멤버
    public object Current
    {
        get
        {
            return array[position];
        }
    }

    //IEnumerator 멤버
    public bool MoveNext()
    {
        if(position == array.Length - 1)
        {
            Reset();
            return false;
        }

        position++;
        return true;
    }

    //IEnumerator 멤버
    public void Reset()
    {
        position = -1;
    }

    //IEnumerable 멤버
    public IEnumerator GetEnumerator()
    {
        return this;
    }
}

class MainApp
{
    static void Main(string[] args)
    {
        MyList list = new MyList();
        for(int i = 0; i < 5; i++)
        {
            list[i] = i;
        }

        foreach(int e in list)
        {
            Console.WriteLine(e);
        }
    }
}

 

'C#' 카테고리의 다른 글

[C#] 예외 처리  (1) 2024.10.09
[C#] Generic T 일반화 프로그래밍  (0) 2024.10.08
[C#] 컬렉션  (0) 2024.10.07
[C#] 배열  (0) 2024.10.07
[C#] 프로퍼티  (1) 2024.10.06