Programming with C#/C# 기초문법

[C# 기초문법] 6. 컬렉션(Collection)

laboputer 2015. 1. 25. 14:48



 

배열(Array)

 C#에서는 배열을 다음과 같이 사용합니다. 

(2차원 배열의 예)

데이터형식 [ , ] 배열이름 = new 데이터형식[2차원길이, 1차원길이];

코드로 보면 다음과 같습니다.

int[,] array = new int[3,2]

{

{1, 2},

{2, 3},

{3, 4}

};

 

또, 가변배열(Jagged Array)도 있습니다. 배열을 요소로 갖는 배열입니다.

데이터형식[][] 배열이름 = new 데이터형식[가변 배열 길이용량][]; 

코드로 보면 다음과 같습니다.

int[][] jaggedarray = new int[3][];

jaggedarray[0]= new int[5] {1,2,3,4,5};

jaggedarray[1]= new int[3] {10,20,30};

jaagedarray[2]= new int[2] {100,200};

 

 

컬렉션(Collection)

 컬렉션이란, 같은 성격을 띠는 데이터의 모음을 담는 자료구조를 말합니다.

보통 같은 성격의 데이터의 묶음들을 배열로 만들어서 사용했지만, C#은 컬렉션이라는 개념으로 배열뿐만 아니라, ArrayList, Queue, Stack, Hashtable 등 여러가지 컬렉션 클래스를 제공합니다. (System.Collections)

이중에서 Hashtable만 사용해보겠습니다.

Hashtable은 Key와 Value가 쌍으로 이루어진 데이터를 다룰때 사용합니다.

자료구조에서도 배우겠지만, 해싱으로 아주 빠른 탐색속도를 자랑합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;
namespace CsharpStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            Hashtable Ht = new Hashtable();
            Ht["하나"] = "One";
            Ht["둘"] = "Two";
            Ht["셋"] = "Three";
           
            Console.WriteLine("요소 직접 접근: {0}", Ht["셋"]);
            
            Console.WriteLine("==Hashtable의 모든 데이터 접근==");
            foreach(var value in Ht.Values)
            {
                Console.WriteLine(value);
            }

            Console.WriteLine("==Hashtable의 모든 Key 접근==");
            foreach (var key in Ht.Keys)
            {
                Console.WriteLine(key);
            }
        }
    }
}
 

 

 

인덱서(Indexer)

 인덱스를 이용하여 객체 내의 데이터에 접근하게 할 수 있습니다.

인덱서를 선언하는 형식은 다음과 같습니다.

class 클래스이름

{

한정사 인덱서형식 this[형식 index]

{

get

{

// index를 이용하여 내부 데이터 반환

}

set

{

     // index를 이용하여 내부 데이터 저장

}

}

}

 

코드를 보겠습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;
namespace CsharpStudy
{
    class MyList
    {
        private int[] array;

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

        public int this[int index]
        {
            get
            {
                return array[index];
            }
            set
            {
                if(index >= array.Length)
                {
                    Array.Resize(ref array, index + 1);                          //무시하세요 태그때문에 
                    Console.WriteLine("array resized : {0}", array.Length);
                }
                array[index] = value;
            }
        }

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

    class Program
    {
        static void Main(string[] args)
        {
            MyList mylist = new MyList();

            Console.WriteLine("==데이터 저장==");
            for(int i=0; i<5; i++)
            {
                mylist[i] = i;
            }

            Console.WriteLine("==데이터 출력==");
            for (int i = 0; i < mylist.Length; i++) // foreach를 사용할 수 없습니다.
            {
                Console.WriteLine(mylist[i]);
            }     
        }
    }
}

 

위와 Mylist라는 객체에 대한 데이터를 인덱스로 접근할 수 있게 만들었습니다.

하지만, 조금만 생각해보면 foreach문은 불가능하다는 사실을 깨닫습니다. 그 이유는

Mylist라는 객체만 보고 요소하나하나를 어떻게 판단할 것이며, 어떻게 순회할지에 대한 약속이 전혀 없기 때문입니다.

그렇다면 foreach문이 가능한 객체는 어떻게 만들 수 있을까요?

 

 

foreach문이 가능한 객체만들기

 foreach문이 가능하기 위해서는 IEnumerable, IEnumerator 를 상속받아야 합니다.

즉, IEnumerable, IEnumerator 를 구현하면서 약속을 정해주어야하는 것입니다.

 

IEnumerable

 메소드

 설명 

 IEnumerator GetEnumerator()

 IEnumerator 형식의 객체를 반환 

IEnumerator

 메소드

 설명 

 boolean MoveNext()

 다음 요소로 이동합니다. 컬렉션의 끝을 지난 경우에는 false, 이동이 성공한 경우에는

true를 반환합니다. 

 void Reset()

 컬렉션의 첫 번째 위치의 '앞'으로 이동합니다. 첫번째 위치가 0번째라면 -1번으로 이

 동합니다. MoveNext()를 호출한 다음에 이루어집니다. 

 Object Current { get; }

 컬렉션의 현재 요소를 반환합니다. 

 

위 인터페이스를 상속받아 구현해보겠습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;
namespace CsharpStudy
{
    class MyList : IEnumerable , IEnumerator
    {
        private int[] array;
        int position = -1;
        public MyList()
        {
            this.array = new int[3];
        }

        public int this[int index]
        {
            get
            {
                return array[index];
            }
            set
            {
                if(index >= array.Length)
                {
                    Array.Resize(ref array, index + 1);         //무시하세요 태그문제때문에
                    Console.WriteLine("array resized : {0}", array.Length);
                }
                array[index] = value;
            }
        }

        public object Current
        {
            get
            {
                return array[position];
            }
        }

        public void Reset()
        {
            position = -1;
        }

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

            position++;
            return (position < array.Length);
        }
        public IEnumerator GetEnumerator()
        {
            for(int i=0; i <array.Length; i++)
            {
                yield return (array[i]);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyList mylist = new MyList();

            Console.WriteLine("==데이터 저장==");
            for(int i=0; i<5; i++)
            {
                mylist[i] = i;
            }

            Console.WriteLine("==데이터 출력==");
            foreach(var item in mylist) // foreach가 가능해졌습니다.
            {
                Console.WriteLine(item);
            }     
        }
    }
}

 

 

 

이상으로 컬렉션에 대해 정리해보았습니다.

 

 


<참고문헌>

뇌를 자극하는 C# 4.0 프로그래밍 - 박상현 저