2014-07-06 5 views
0

방금 ​​입력 한 키가 존재하지 않는다는 나의 사전이 왜입니까? 내 Equals 방법 또는 이중 비교와 관련이 있습니까?존재할 때 사전 키를 찾을 수 없음

// Test: I know the dictionary contains nCoord but its saying the key doesn't exist 
Dictionary<UTMCoordinate, int> planes = new Dictionary<UTMCoordinate, int>(); 
UTMCoordinate nCoord = new UTMCoordinate(337394.136407966, 6263820.40182064, 0, 56, UTMCoordinate.Hemisphere.H_SOUTHERN); 
planes[nCoord]   = 1; 

bool exists = planes.ContainsKey(nCoord); // always returns false 

UTMCoordinate의 내 구현은 다음과 같습니다 :

public class UTMCoordinate 
{ 
    public enum     Hemisphere {H_NOTHERN, H_SOUTHERN}; 
    public const double   DIF_TOLERANCE = 0.0005; 
    public double    x    { get; set; } 
    public double    y    { get; set; } 
    public double    elev   { get; set; } 
    public uint     UTMZone   { get; set; } 
    public Hemisphere   hemisphere  { get; set; } 

    public UTMCoordinate(double x, double y, double elev=double.MinValue, uint utmZone=uint.MinValue, Hemisphere hemisphere=Hemisphere.H_SOUTHERN) { 
     this.x   = x; 
     this.y   = y; 
     this.elev  = elev; 
     this.UTMZone = utmZone; 
     this.hemisphere = hemisphere; 
    } 

    public override int GetHashCode() { 
     unchecked // Overflow is fine, just wrap 
     { 
      int hash = 17; 
      // Suitable nullity checks etc, of course :) 
      hash = hash * 23 + x.GetHashCode(); 
      hash = hash * 23 + y.GetHashCode(); 
      hash = hash * 23 + elev.GetHashCode(); 
      hash = hash * 23 + UTMZone.GetHashCode(); 
      hash = hash * 23 + hemisphere.GetHashCode(); 
      return hash; 
     } 
    } 

    public override bool Equals(object obj) 
    { 
     UTMCoordinate other = obj as UTMCoordinate; 
     if (other == null) 
      return false; 

     return double.Equals(x, other.x) && double.Equals(y, other.y) && double.Equals(elev, other.elev) && uint.Equals(UTMZone, other.UTMZone) && double.Equals(hemisphere, other.hemisphere); 
    } 
} 

편집 내가 다른 더블을 비교 한 방법을 사용했습니다 다니엘 A. 백상 조언을 사용하여 다음

는 코드입니다. 나는 귀하의 질문에서 코드를 가지고가는 경우에

public override bool Equals(object obj) 
{ 
    //return base.Equals (obj); 
    UTMCoordinate other = obj as UTMCoordinate; 
    if (other == null) 
     return false; 

    //return double.Equals(x, other.x) && double.Equals(y, other.y) && double.Equals(elev, other.elev) && uint.Equals(UTMZone, other.UTMZone) && double.Equals(hemisphere, other.hemisphere); 
    return Math.Abs (x-other.x) <= DIF_TOLERANCE && Math.Abs (y-other.y) <= DIF_TOLERANCE && Math.Abs (elev-other.elev) <= DIF_TOLERANCE && uint.Equals(UTMZone, other.UTMZone) && hemisphere == other.hemisphere; 
} 
+0

fyi double에는 고정 된 정밀도가 없습니다. 그것은 당신에게 단서를 줄 수 있습니다. –

+0

두 가지 방법 모두에 중단 점을 지정하십시오. 그들이 기대할 때 그들이 부름을 받는가? 그들은 당신이 기대하는 가치를 반환합니까? –

+2

방금 ​​시도했습니다. 'planes.ContainsKey (nCoord)'는 나에게'true'를 reture했다. – AlexD

답변

3

: 나는 exists 얻을

Dictionary<UTMCoordinate, int> planes = new Dictionary<UTMCoordinate, int>(); 
UTMCoordinate nCoord = new UTMCoordinate(337394.136407966, 6263820.40182064, 0, 56, UTMCoordinate.Hemisphere.H_SOUTHERN); 
planes[nCoord]   = 1; 

bool exists = planes.ContainsKey(nCoord); 

값은 true입니다 불행하게도 그 여전히 키를 식별하지. 내가 할 경우

그러나,이 :

nCoord.x = 1.0; 
exists = planes.ContainsKey(nCoord); 

exists의 값이 갑자기 개체가 사전에 여전히에도 불구하고 false된다. GetHashCode의 값이 변경 되었기 때문입니다. -1473667404 이었지만, x 속성을 할당 한 후 201352392이됩니다.

사전은 GetHashCode 값을 사용하여 키를 넣을 버킷을 결정하므로 해시 코드가 변경 될 때 사전이 잘못된 버킷에서 키를 찾은 다음 키가 없다고보고 할 수 있습니다.

나는 당신의 코드에서 무슨 일이 일어나고 있는지 의심 스럽다.

그래서 개체를 변경하여 불변으로 변경해야합니다.

public double    x    { get; private set; } 
public double    y    { get; private set; } 
public double    elev   { get; private set; } 
public uint     UTMZone   { get; private set; } 
public Hemisphere   hemisphere  { get; private set; } 

그런 다음 생성자 외부의 값을 변경하지 마십시오.