2014-07-06 3 views
1

키가 될 클래스 XX와 값이 될 클래스 YY를 포함하는 사전을 만들고 싶습니다.사전 정의 키를 정의 할 수있는 클래스를 만드는 방법은 무엇입니까?

사전은

class XX 
{ 
    int t1; 
    char t2; 

    string Key() 
    { 
     return string.Format("{0}{1}", t1, t2); 
    } 
} 

내가 사전 키가 실제로 XX하지만 클래스 XX의 '키'등을 사용하는 것을 정의하기 위해 어떻게 든 원하는 XX 클래스 코드를

Dictionary<XX, YY> myDictionary; 

로 정의하다 사전의 실제 키.

가능합니까?

답변

8

첫 번째 방법

당신은 XX의 두 가지 방법 오버라이드 (override) 할 필요가 : 같은 수를 반환하는 두 개의 인스턴스가 같은지

  • GetHashCode을인지 사전을 말할 것이다

    • Equals을, 2 개의 인스턴스가 동일한 경우. 두 인스턴스가 같지 않은 경우에도 동일한 수를 반환 할 수 있지만 가능한 한 고유해야합니다.

  • 당신은 또한 명시 적 어떤지를 비교할 수 있습니다 XX 것을 mkae 것이다 XX 클래스 IEquatable<XX>를 구현할 수 있습니다.

    class XX : IEquatable<XX> 
    { 
        int t1; 
        char t2; 
    
        public override bool Equals(object other) 
        { 
         return Equals(other as XX); 
        } 
    
        public bool Equals(XX other) 
        { 
         return other != null 
          && t1 == other.t1 
          && t2 == other.t2; 
        } 
    
        public override int GetHashCode() 
        { 
         return t1^(397 * t2.GetHashCode()); 
        } 
    } 
    

    두 번째 방법

    IEqualityComparer<XX>를 구현하는 클래스를 작성하고 사전의 생성자에 전달합니다. 동일한 두 가지 방법을 구현해야하지만 논리는 XX과 분리되어 다른 키 스키마로 다른 사전을 만들 수 있습니다. 그런 다음

    class XXEqualityComparer : IEqualityComparer<XX> 
    { 
        public static readonly XXEqualityComparer Instance = new XXEqualityComparer(); 
    
        private XXEqualityComparer() 
        { 
        } 
    
        public bool Equals(XX x, XX y) 
        { 
         if (ReferenceEquals(x, y)) 
          return true; 
    
         if (x == null || y == null) 
          return false; 
    
         return x.t1 == y.t1 
          && x.t2 == y.t2; 
        } 
    
        public int GetHashCode(XX obj) 
        { 
         return obj == null ? 0 : obj.t1^(397 * obj.t2.GetHashCode()); 
        } 
    } 
    

    :

    var myDictionary = new Dictionary<XX, YY>(XXEqualityComparer.Instance); 
    

    세 번째 방법

    KeyedCollection<XX, string>으로 사전을 교체합니다. 항목의 키를 제공하려면 GetKeyForItem 메서드를 재정의해야합니다.

    class XXKeyedCollection : KeyedCollection<XX, string> 
    { 
        protected override string GetKeyForItem(XX item) 
        { 
         return string.Format("{0}{1}", t1, t2); 
        } 
    } 
    

    중요

    작업 사전 키가 사전 키로 사용되는 동안 을 변경하지 않아야 개체를하기 위해 유의하시기 바랍니다. 보다 정확하게는 Equals 또는 GetHashCode의 결과에 영향을 줄 수있는 필드/속성을 변경하면 안됩니다.

    2

    사전 클래스는 키 객체에 대해 GetHashCode() 메소드를 사용하여 해시 테이블에서 키를 생성합니다. 필요에 따라 반환하려면 XX 클래스에서 재정의하십시오.하지만 조심하십시오 (같은 키가있는 다른 XX 인스턴스가 사전에있는 경우 어떻게 될지 생각하십시오).

    +1

    다른 인스턴스는 동일한 해시 코드를 가질 수 있습니다. 이 경우, 'Equals' 메쏘드는 평등을 결정합니다. 그래서 항상 ** ** Equals와 ** GetHashCode를 모두 재정의해야합니다. –

    관련 문제