C# 기초 정리: 배열, 컬렉션, 인덱서

Table of Content

가변 배열(Jagged Array)

  • 가변 배열의 요소는 차원과 크기가 서로 다른 “배열”
  • 다차원 배열을 사용하는 것보다 공간 절약
class Program
{
    static void Main(string[] args)
    {
        /* 가변 배열(Jagged Array) */
        int[][] jagged = new int[3][];
        jagged[0] = new int[] { 1, 2, 3 };
        jagged[1] = new int[] { 4, 5, 6, 7, 8 };
        jagged[2] = new int[] { 9, 10 };
 
        foreach(int[] arr in jagged)
        {
            Console.WriteLine("Length: {0}", arr.Length);
            foreach (int i in arr)
                Console.Write("{0} ", i);
            Console.WriteLine();
        }
    }
}

 

컬렉션(Collection)

  • 같은 성격의 데이터를 담는 자료구조​
  • 배열도 .NET 프레임워크가 제공하는 컬렉션 자료구조의 일부​
  • 사용 시 using System.Collections; 추가​
  • 종류: ArrayList, Queue, Stack, Hashtable 등​
class Program
{
    static void Main(string[] args)
    {
        /* ArrayList: 배열과 닮은 컬렉션 
         * 생성 시 용량을 지정할 필요가 없음 (가변 용량) */
        ArrayList list = new ArrayList();
        list.Add(1);
        list.Add(3.14);
        list.Add("안녕요?ㅎ"); // Add(): 마지막 요소에 새 요소 추가
        list.RemoveAt(1); // RemoveAt(): 특정 인덱스에 있는 요소 제거
        list.Insert(1, "C#"); // Insert(): 특정 인덱스에 요소 추가
        Console.Write("ArrayList: ");
        foreach (var v in list)
            Console.Write("{0} / ", v);
        Console.WriteLine();
 
        /* Queue: 입력된 순서대로 하나씩 꺼내 ​처리하기 위한 컬렉션
         * 입력은 반드시 뒤에서, 출력은 반드시 앞에서 이루어짐 */
        Queue q = new Queue();
        q.Enqueue(1);
        q.Enqueue("안녕요?ㅎ");
        q.Enqueue(2.5); // Enqueue(): 입력
        q.Dequeue(); // Dequeue: 출력 후 데이터 반환
        Console.Write("Queue: ");
        while (q.Count > 0)
            Console.Write("{0} / ", q.Dequeue());
        Console.WriteLine();
 
        /* Stack: 후입선출(LIFO: Last In First Out) 구조 */
        Stack s = new Stack();
        s.Push(1);
        s.Push("안녕요?ㅎ");
        s.Push(2.5); // Push(): 입력
        s.Pop(); // Pop(): 출력 후 데이터 반환
        Console.Write("Stack: ");
        while (s.Count > 0)
            Console.Write("{0} / ", s.Pop());
        Console.WriteLine();
 
        /* Hashtable: 키와 값의 쌍으로 이루어진 ​데이터의 집합​
         * 해싱(Hashing)을 이용: ​키를 이용하여 단번에 데이터가 ​저장된 컬렉션 내의 주소를 계산 */
        Hashtable ht = new Hashtable();
        ht["C"] = "씨";
        ht["C++"] = "씨뿔뿔";
        ht["C#"] = "씨샵";
        Console.Write("Hashtable: ");
        Console.Write("{0} / ", ht["C#"]);
        Console.Write("{0} / ", ht["C"]);
        Console.Write("{0} / ", ht["C++"]);
        Console.WriteLine();
    }
}

 

인덱서(Indexer)

  • 인덱스(Index)를 이용하여 객체 내의 데이터에 접근하게 해주는 프로퍼티
class MyList
{
    /* 인덱서가 제어할 배열 */
    private int[] array;
 
    /* 생성자 */
    public MyList()
    {
        array = new int[3];
    }
 
    /* 배열의 길이를 반환하는 프로퍼티 */
    public int Length
    {
        get { return array.Length; }
    }
    
    /* 인덱서 선언: 한정자 인덱서_형식 this[형식 매개변수명] */
    public int this[int index]
    {
        get
        {
            return array[index];
        }
 
        set
        {
            /* 인덱스가 배열 길이보다 크면 배열 Resize */
            if (index >= array.Length)
                Array.Resize<int>(ref array, index + 1);
 
            /* 인덱서를 이용하여 배열에 값 설정 */ 
            array[index] = value;
        }
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        MyList list = new MyList();
        
        /* 인덱서를 이용한 데이터 입력 */
        for (int i = 0; i < 10; i++)
            list[i] = i;
 
        /* 인덱서를 이용한 데이터 출력 */
        for (int i = 0; i < 10; i++)
            Console.WriteLine(list[i]);
 
    }
}

 

foreach가 가능한 객체 생성

  • foreach 문은 IEnumerable, IEnumerator 인터페이스를 상속하는 형식만 지원​
  • 구현해야 하는 메소드
    • IEnumerable IEnumerator GetEnumerator(): IEnumerator 형식의 객체 반환
    • IEnumerator boolean MoveNext(): 다음 요소로 이동. 이동 성공 시 true, 컬렉션의 끝을 지날 시 false 반환
    • IEnumerator void Reset(): 컬렉션의 첫번째 위치의 “앞”으로 이동. -1번으로 이동.
    • IEnumerator object Current { get; }: 컬렉션의 현재 요소를 반환하는 프로퍼티
/* foreach가 가능한 객체는 
 * IEnumerable과 IEnumerator 인터페이스를 상속받는 객체여야 함 */
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);
            array[index] = value;
        }
    }
 
    /* IEnumerable 멤버 */
    /* GetEnumerator(): IEnumerator 형식의 객체 반환 */
    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < array.Length; i++)
            yield return array[i]; // yield 키워드: 컬렉션 데이터를 하나씩 리턴
    }
 
    /* IEnumerator 멤버 */
    /* MoveNext(): 다음 요소로 이동 */
    public bool MoveNext()
    {
        /* 컬렉션의 끝을 지나면 위치 초기화 & false 리턴 */
        if(position == array.Length - 1)
        {
            Reset();
            return false;
        }
 
        /* 컬렉션의 끝이 아니면 다음 요소로 이동 & true 리턴 */
        position++;
        return (position < array.Length);
    }
 
    /* Current 프로퍼티: 컬렉션의 현재 요소 반환 */
    public object Current
    {
        get { return array[position]; }
    }
 
    /* Reset(): 컬렉션의 첫번째 위치의 앞(-1번째)로 이동 */
    public void Reset()
    {
        position = -1;
    }
}
 
class Program
{
    public static void Main(string[] args)
    {
        MyList list = new MyList();
 
        /* 인덱서를 이용한 데이터 입력 */
        for (int i = 0; i < 10; i++)
            list[i] = i;
 
        /* foreach를 이용하여 값 출력 */
        foreach (int i in list)
            Console.WriteLine(i);
    }
}

 

댓글 남기기