복잡한 동등성을 위해 Object.GetHashCode()를 구현하려면 어떻게 해야 합니까?

StackOverflow https://stackoverflow.com/questions/1072058

문제

기본적으로 지금까지 다음이 있습니다.

class Foo {
    public override bool Equals(object obj)
    {
        Foo d = obj as Foo ;
        if (d == null)
            return false;

        return this.Equals(d);
    }

    #region IEquatable<Foo> Members

    public bool Equals(Foo other)
    {
        if (this.Guid != String.Empty && this.Guid == other.Guid)
            return true;
        else if (this.Guid != String.Empty || other.Guid != String.Empty)
            return false;

        if (this.Title == other.Title &&
            this.PublishDate == other.PublishDate &&
            this.Description == other.Description)
            return true;

        return false;
    }
}

그래서 문제는 이렇습니다.필수가 아닌 필드가 있습니다. Guid, 이는 고유 식별자입니다.이것이 설정되지 않은 경우 두 개체가 동일한지 확인하기 위해 덜 정확한 측정항목을 기반으로 동일성을 확인해야 합니다.이것은 잘 작동하지만 GetHashCode() 지저분한...어떻게 해야 합니까?순진한 구현은 다음과 같습니다.

public override int GetHashCode() {
    if (this.Guid != String.Empty)
        return this.Guid.GetHashCode();

    int hash = 37;
    hash = hash * 23 + this.Title.GetHashCode();
    hash = hash * 23 + this.PublishDate.GetHashCode();
    hash = hash * 23 + this.Description.GetHashCode();
    return hash;
}

그러나 두 가지 유형의 해시가 충돌할 가능성은 얼마나 됩니까?물론, 그럴 거라고는 기대하지 않겠지만 1 in 2 ** 32.이것은 나쁜 생각입니까? 그렇다면 어떻게 해야 합니까?

도움이 되었습니까?

해결책

나는 당신이 사용하기로 선택한 접근법에 문제가 있다고 생각하지 않습니다. 해시 충돌에 대한 '너무 많은'걱정은 거의 항상 문제를 지나치게 생각하는 것을 나타냅니다. 해시가 다를 가능성이 높으면 괜찮을 것입니다.

궁극적으로 당신은 심지어 Description 어쨌든 당신의 해시에서 어쨌든 대부분의 시간 개체는 제목과 출판 날짜 (책?)에 따라 구별 될 수 있다고 기대하는 것이 합리적입니다.

해시 함수의지도를 모두 무시하는 것을 고려하고 Equals 해시 충돌의 가능성이 낮은 (?) 사례를 명확하게하기위한 구현.

다른 팁

아주 쉬운 사용자 정의 클래스에 대한 해시 코드 방법 각 필드의 해시 코드를 비트 단위로 XOR하는 것입니다.다음과 같이 간단할 수 있습니다.

int hash = 0;
hash ^= this.Title.GetHashCode();
hash ^= this.PublishDate.GetHashCode();
hash ^= this.Description.GetHashCode();
return hash;

로부터 위의 링크:

XOR에는 다음과 같은 좋은 속성이 있습니다.

  • 계산 순서에 의존하지 않습니다.
  • 비트를 "낭비"하지 않습니다.구성요소 중 하나라도 비트를 변경하면 최종 값이 변경됩니다.
  • 가장 원시적인 컴퓨터에서도 단일 주기로 빠릅니다.
  • 균일한 분포를 유지합니다.결합한 두 조각이 균일하게 분포되어 있으면 결합도 마찬가지입니다.즉, 다이제스트의 범위를 더 좁은 밴드로 축소하는 경향이 없습니다.

XOR을 수행하면 중복 값이 ​​서로 상쇄되므로 필드에 중복 값이 ​​있을 것으로 예상되는 경우 XOR이 제대로 작동하지 않습니다.이 경우에는 문제가 되지 않는 세 개의 관련되지 않은 필드를 함께 해싱하고 있기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top