C# 평등 계약을 위반하는 클래스의 해시 코드를 선택하는 방법은 무엇입니까?

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

  •  08-07-2019
  •  | 
  •  

문제

어떤 이유로 든 공무원을 따르지 않는 여러 수업이 있습니다. Equals 계약. 덮어 쓰기에서 GetHashCode() 이 클래스는 단순히 0을 반환하여 해시 맵에서 사용할 수 있습니다.

이 클래스 중 일부는 동일한 인터페이스를 구현 하며이 인터페이스를 키로 사용하는 해시 맵이 있습니다. 그래서 나는 모든 수업이 적어도 다른 (그러나 여전히 일정한) 값을 반환해야한다고 생각했습니다. GetHashCode().

문제는이 값을 선택하는 방법입니다. 단순히 첫 번째 클래스 리턴 1, 다음 클래스 2 등을 반환해야합니까? 아니면 같은 것을 시도해야합니다

class SomeClass : SomeInterface {
    public overwrite int GetHashCode() {
        return "SomeClass".GetHashCode();
    }
}

해시가 더 고르게 분포되어 있습니까? (반환 된 값을 직접 캐시해야합니까? 아니면 Microsoft의 컴파일러가 이것을 최적화 할 수 있습니까?)

업데이트: 동등한 계약을 위반하기 때문에 각 객체에 대해 개별 해시 코드를 반환 할 수 없습니다. 구체적으로, 나는 언급하고 있습니다 이 문제.

도움이 되었습니까?

해결책

벡터 클래스를 쓸 때이 정확한 문제를 해결했습니다. 벡터를 평등과 비교하고 싶었지만 플로트 작업은 반올림 오류를 제공하므로 대략적인 평등을 원했습니다. 간단히 말하면, 우선 순위 평등은 구현이 대칭적이고 반사적이며 전이되지 않는 한 나쁜 생각입니다.

다른 클래스는 Equals에 해당 속성이 있다고 가정하므로 해당 클래스를 사용하여 수업이 있으므로 이상한 경우에도 끝날 수 있습니다. 예를 들어, 목록은 고유성을 시행 할 수 있지만 일부 요소 B와 동일하게 평가되는 두 가지 요소로 끝납니다.

해시 테이블은 평등을 깨뜨릴 때 예측할 수없는 행동의 완벽한 예입니다. 예를 들어:

//Assume a == b, b == c, but a != c
var T = new Dictionary<YourType, int>()
T[a] = 0
T[c] = 1
return T[b] //0 or 1? who knows!

또 다른 예는 세트입니다.

//Assume a == b, b == c, but a != c
var T = new HashSet<YourType>()
T.Add(a)
T.Add(c)
if (T.contains(b)) then T.remove(b)
//surely T can't contain b anymore! I sure hope no one breaks the properties of equality!
if (T.contains(b)) then throw new Exception()

Exequals와 같은 이름을 가진 다른 방법을 사용하는 것이 좋습니다. == 연산자가 가상이 아니기 때문에 평등과 같은 다른 클래스에서 우연히 사용하지 않기 때문에 == 연산자를 재정의하는 것을 고려할 수도 있습니다.

해시 테이블의 참조 평등을 실제로 사용할 수 없다면 가능한 경우 사례의 성능을 망치지 마십시오. IAPProxequals 인터페이스를 추가하고 클래스에서 구현 한 다음 사전에 getApprox를 추가하여 키를 열거하는 키를 열거하고 관련 값을 반환합니다. 특히 3 차원 벡터 또는 필요한 모든 것에 대해 맞춤 사전을 작성할 수도 있습니다.

다른 팁

그것이 "평등 계약을 위반하는"경우, 키로 사용해야한다고 확신하지 못합니다.

그것은 그것을 열쇠로 사용하고 있습니다. 당신은 정말로 해싱을 제대로 가져와야합니다 ... 그것은 무엇을 매우 불분명합니다. Equals 논리는이지만 동등한 것으로 간주되는 두 가지 값은 ~ 해야 하다 동일한 해시 코드가 있습니다. 동일한 해시 코드를 가진 두 값이 동일 할 필요는 없습니다.

상수 문자열을 사용하면 실제로 큰 도움이되지 않습니다. 유형보다 값을 고르게 분할하게 될 것입니다.

나는 추론이 무엇인지 궁금합니다 GetHashCode() 그리고 일정한 가치를 반환합니다. "계약"을 위반하는 것이 아니라 해시의 아이디어를 위반하는 이유 GetHashCode() 전혀 기능하고 기본 구현을 남겨 두십시오 Object?

편집하다

당신이 한 일이라면, 당신은 당신이 그들의 참조 대신 내용을 기준으로 객체를 일치 시키도록한다면, 다른 클래스를 사용하면 다른 상수를 사용하면 제안하는 것은 단순히 다른 상수를 사용하지만 비효율적입니다. 당신이하고 싶은 것은 클래스의 내용을 취할 수있는 해싱 알고리즘을 제시하고 짝수 분포와의 균형을 맞추는 값을 생성하는 것입니다 (해싱 101).

나는 당신이 무엇을 찾고 있는지 확실하지 않은 것 같아요 ...이 패러다임에 대한 일정한 숫자를 선택할 수있는 "좋은"체계가 없습니다. 하나는 다른 것보다 낫지 않습니다. 실제 해시를 만들도록 객체를 개선하십시오.

해시 충돌이 발생하면 해시 가능/사전은 호출하여 원하는 키를 찾기 위해 동일합니다. 상수 해시 코드를 사용하면 처음에 해시를 사용하는 속도 이점이 제거됩니다. 이는 선형 검색이됩니다.

계약에 따라 Equals 방법이 구현되지 않았다고 말합니다. 정확히 무엇을 의미합니까? 위반의 종류에 따라 해시 가능 또는 사전은 단순히 느리게 (선형 검색) 작동하지 않습니다.

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