[C#] 8.2.4 IDictionary 인터페이스

IDictionary 인터페이스는 키와 값을 쌍으로 보관하는 컬렉션들의 기반 형식입니다. 그리고 IList 인터페이스처럼 IDictionary 인터페이스도 ICollection 인터페이스를 기반으로 정의한 형식입니다.

IDictionary 인터페이스에는 키와 값을 쌍으로 보관할 때 사용하는 Add 메서드를 제공하고 있으며 내부 규칙에 따라 보관될 위치를 결정하게 됩니다. 따라서 IList 인터페이스와 다르게 특정 위치에 보관하는 Insert 메서드는 제공하지 않습니다. 그리고 IDictionary 인터페이스에는 같은 키를 가진 요소를 보관할 수 없습니다. 만약, Add 메서드를 이용하여 같은 키를 가진 요소를 보관하려고 시도하면 예외가 발생합니다.

void Add(object key, object value); //키와 값을 쌍으로 보관하는 메서드

▶ Add 메서드를 이용하여 요소(키와 값을 쌍으로 함) 보관

static void Main(string[] args)
{
    Hashtable ht = new Hashtable();
    ht.Add("홍길동", "율도국");
    ht.Add("장언휴", "이에이치");

    foreach (DictionaryEntry d in ht)
    {
        Console.WriteLine("{0}:{1}",d.Key,d.Value);
    }
}

▶ 실행 결과

홍길동:율도국
장언휴:이에이치

IDictionary 인터페이스에서는 인덱서를 사용할 때 키를 입력 인자로 전달하면 값을 참조할 수 있습니다. 그리고 인덱서를 대입 연산자 좌항에 사용하면 보관된 요소의 값이 바뀌게 됩니다. 만약, 해당 키를 갖는 요소가 없다면 키와 값을 쌍으로 보관해 줍니다. Add 메서드에서는 같은 키가 보관되어 있을 때 예외를 발생하지만, 인덱스는 예외를 발생하지 않고 보관된 값을 변경합니다.

object this[object key]{    get;     set;    } //인덱서

object this[object key]{    get;     set;    } //인덱서

▶ Hashtable의 인덱서 사용

static void Main(string[] args)
{
    Hashtable ht = new Hashtable();
    ht["홍길동"]= "율도국";
    ht["장언휴"]= "이에이치";
    ht["홍길동"] = "대한민국";

    foreach (DictionaryEntry d in ht)
    {
        Console.WriteLine("{0}:{1}",d.Key,d.Value);
    }
}

▶ 실행 결과

장언휴:이에이치
홍길동:대한민국

IDictionary 인터페이스에서는 특정 키에 해당하는 요소를 제거하는 Remove 메서드를 제공합니다. IList 인터페이스에서는 특정 위치에 요소를 제거하는 RemoveAt 메서드를 제공하지만, IDictionay 인터페이스에서는 키를 기준으로 키와 값을 쌍으로 보관하기 때문에 RemoveAt 메서드를 제공하지 않습니다. 하지만 보관된 모든 요소를 제거하는 메서드인 Clear는 제공합니다.

void Remove(object key); //특정 키에 해당하는 요소를 제거하는 메서드
void Clear(); //보관된 모든 요소를 제거하는 메서드

void Remove(object key); //특정 키에 해당하는 요소를 제거하는 메서드

void Clear(); //보관된 모든 요소를 제거하는 메서드

▶ IDictionary 개체에 보관한 요소 제거하기

static void Main(string[] args)
{
    Hashtable ht = new Hashtable();
    ht["홍길동"]= "율도국";
    ht["장언휴"]= "이에이치";
    ht["김 구"] = "대한민국";

    ht.Remove("홍길동");
    foreach (DictionaryEntry d in ht)
    {
        Console.WriteLine("{0}:{1}",d.Key,d.Value);
    }

    ht.Clear();
    Console.WriteLine("보관된 요소 개수:{0}",ht.Count);
}

▶ 실행 결과

김 구:대한민국
장언휴:이에이치
보관된 요소 개수:0

IDictionary 인터페이스에서는 특정 키의 요소가 보관되었는지 확인하는 Contains 메서드를 제공합니다. 그리고 키를 보관하는 컬렉션을 가져오는 Keys 속성과 값을 보관하는 컬렉션을 가져오는 Values 속성을 제공합니다. 특이한 사항으로는 키와 값으로 보관을 하기 때문에 foreach 문에서 열거할 때 DictionaryEntry 형식으로 보관된 요소를 접근하게 제공하고 있습니다. 이를 위해 IDictionaryEnumerator를 반환하는 GetEnumerator 메서드를 제공하고 있습니다.

▶ Hashtable 형식 개체 foreach 구문 사용

static void Main(string[] args)
{
    Hashtable ht = new Hashtable();
    ht["홍길동"]= "율도국";
    ht["장언휴"]= "이에이치";

    Console.WriteLine("키 항목");
    foreach (string s in ht.Keys)
    {
        Console.WriteLine("    {0}",s);
    }
    Console.WriteLine("값 항목");
    foreach (string s in ht.Values)
    {
        Console.WriteLine("    {0}",s);
    }
    Console.WriteLine("키:값");
    foreach (DictionaryEntry d in ht)
    {
        Console.WriteLine("    {0}:{1}", d.Key, d.Value);
    }
}

이 외에도 컬렉션이 고정 사이즈인지 읽기만 가능한지를 가져오기 가능한 IsFixedSize 속성과 IsReadOnly 속성을 제공합니다.

▶ IDictionary 인터페이스에서 약속한 멤버들

interface IDictionary:ICollection
{
    void Add(object key, object value); //키와 값을 쌍으로 보관하는 메서드
    void Clear(); //보관된 모든 요소를 제거하는 메서드
    bool Contains(object key); //보관된 요소의 특정 키가 있는지 확인하는 메서드
    IDictionaryEnumerator GetEnumerator();//foreach에서 요소를 열거하기 위한 메서드
    bool IsFixedSize{    get;    } //고정 사이즈 속성 - 가져오기
    bool IsReadOnly{    get;    } //읽기만 가능한지에 대한 속성 - 가져오기
    ICollection Keys{    get;    } //키 컬렉션 속성 - 가져오기
    void Remove(object key); //특정 키에 해당하는 요소를 제거하는 메서드
    ICollection Values{    get;    } //값 컬렉션 속성 - 가져오기
    object this[object key]{    get;     set;    } //인덱서 

    #region ICollection 멤버
    void CopyTo(Array array, int index);
    int Count{    get;    }
    bool IsSynchronized{    get;    }
    object SyncRoot{    get;    }
    #endregion
    #region IEnumerable 멤버
    IEnumerator IEnumerable.GetEnumerator();
    #endregion
}

이처럼 C#에서 제공하는 컬렉션은 일반적으로 필요한 멤버를 추상화하여 인터페이스 기반으로 정의하였습니다. 여러분은 하나의 컬렉션을 사용할 수 있다면 다른 컬렉션도 어렵지 않게 사용할 수 있을 것입니다.