2012-12-29 4 views
2

제 수업에서는 EqualsGetHashCode을 구현했습니다. 내 C# 코드에서 사전에 대한 키로 사용할 때 아직, 나는 오류가 발생합니다 : "Key not found exception" 감사합니다,GetHashCode가 구현되었지만 사전에서 키를 찾을 수 없습니까?

public class Time: IEquatable<Time> 
{ 
    public String hour; 
    public String minute; 

    public Time() 
    { 
     hour = "00"; 
     minute = "00"; 
    } 

    public Time(String hour, String minute) 
     : this() 
    { 
     this.hour = hour; 
     this.minute = minute; 
    } 

    public override int GetHashCode() 
    { 
     int hash = int.Parse(hour) * 60 + int.Parse(minute); 
     return hash.GetHashCode(); 
    } 
    public override bool Equals(Time time) 
    { 

      return (this.hour == time.hour && this.minute == time.minute); 

    } 

} 

그리고 내가 그것을 사용하고 코드 :

Dictionary<Time, int> time2RowIndex = new Dictionary<Time, int>(); 

을 ...

int beginRow = 0; 
if(time2RowIndex.ContainsKey(time.hour)) 
     beginRow = time2RowIndex [time.hour]; 
+0

'리소스'란 무엇입니까? '시간'의 인스턴스입니까? – dtb

+0

@dtb 실제 코드에서 Time 클래스는 Resource 클래스의 서브 클래스입니다! 시간은 '시간'이어야합니다! –

답변

4

보십시오. 트릭은 IEquatable<>을 구현하는 대신 객체 (GetHashCode)에서 Equals을 무시하는 것입니다.

또한, Hour 또는 Time의 인스턴스가 사전 버킷에 추가 된 후 Time 객체 변화에 Minute 경우 더 이상의 해시 코드와 일치하지 않습니다 (추가시 해시 코드에 의해 선택)

목적. 즉, 사전에 동일한 값의 객체 (예 : ContainsKey)를 표시하더라도 사전에있는 원래 항목을 찾지 못합니다 (해시 버킷에는 원래 객체가 포함되어 있지 않기 때문에). 이러한 상황을 피하기 위해 GetHashCode 함수에서 참조되는 모든 필드를 읽기 전용으로하는 것이 가장 좋습니다.

public class Time : IEquatable<Time> 
{ 
    public String Hour; 
    public String Minute; 

    public Time() 
    { 
     Hour = "00"; 
     Minute = "00"; 
    } 

    public Time(String hour, String minute) 
     : this() 
    { 
     this.Hour = hour; 
     this.Minute = minute; 
    } 

    public override int GetHashCode() 
    { 
     return int.Parse(Hour) * 60 + int.Parse(Minute); 
    } 

    public override bool Equals(object obj) 
    { 
     var time = obj as Time; 
     return !ReferenceEquals(time, null) && Equals(time); 
    } 

    public bool Equals(Time time) 
    { 
     return string.Equals(Hour, time.Hour, StringComparison.Ordinal) && string.Equals(Minute, time.Minute, StringComparison.Ordinal); 
    } 
} 
+1

감사합니다. @mlorbetske는 작동했지만 오류에 대해 설명해 주시겠습니까? Equals (object obj)를 구현하지 않았기 때문에 오류가 발생했을 것입니다. 권리? –

+1

네,'object.Equals'는 해시 코드를 사용하여 사전에서 후보 키를 찾은 후에 수행되는 동등성 검사에 사용됩니다. 구현되지 않았기 때문에'IEquatable.Equals' 메쏘드는 실제로 동등하다는 것을 주장하기 위해 호출되지 않았습니다. – mlorbetske

관련 문제