2014-12-08 1 views
3

나는 부울, 문자열 및 부동 소수점을 결합한 간단한 F # 구분 된 공용체가 있습니다. 이 조합의 Object.Equals (arg)를 재정의하여 부동 소수점을 확인할 때 정밀 오류를 설명 할 수 있도록 엡실론을 넣을 수 있도록하려고합니다. 컴파일러는 내가 this.Equals (arg)를 재정의하면 this.GetHashCode()와 this.CompareTo (arg)도 재정의해야한다고 불평했다. 이러한 재정의를 위해 특별한 기능을 계획하지 않았으므로이 메소드의 기본 버전을 호출하기 만하면됩니다. 이제 구현할 때마다 GetHashCode에 대한 세 번의 호출과 차별화 된 공용 구조의 각 유형에 대한 CompareTo에 대한 세 가지 호출 (각 유형별로 하나씩)이 있습니다.F #에서 차별화 된 Union에 대해 GetHashCode 및 CompareTo를 어떻게 재정의합니까?

GetHashCode를 한 번 호출하여 GetHashCode 재정의를 코딩하는 방법이 있습니까? CompareTo에 대해 같은 질문이 있습니까? 차별화 된 노조의 모든 유형은 ICompareable을 구현합니다.

member this.Value = 
    match this with 
    | Bool(b) -> box b 
    | Str(s) -> box s 
    | Float(f) -> box f 

그럼 당신은 그냥 권투를 포함 값을 (얻어서 GetHashCode을 구현할 수 있습니다, 그래서는 다음과 같습니다

[<CustomEquality;CustomComparison>] 
type MyType = 
    | Bool of bool 
    | Str of string 
    | Float of float 

    override this.Equals(arg) = 
     let epsilon = 0.1 
     match arg with 
     | :? MyType as other -> 
      match this, other with 
      | Bool(a), Bool(b) -> a = b 
      | Str(a), Str(b) -> a = b 
      | Float(a), Float(b) -> Math.Abs(a - b) < epsilon 
      | _ -> false 
     | _ -> false 

    override this.GetHashCode() = 
     match this with 
     // Three calls to GetHashCode. I'd like only one 
     | Bool(a) -> a.GetHashCode() 
     | Str(a) -> a.GetHashCode() 
     | Float(a) -> a.GetHashCode() 
     | _ -> 0 

    interface System.IComparable with 
     member this.CompareTo arg = 
      match arg with 
       | :? MyType as other -> 
        match this, other with 
        // Three calls to CompareTo. I'd like only one 
        | Bool(a), Bool(b) -> a.CompareTo(b) 
        | Str(a), Str(b) -> a.CompareTo(b) 
        | Float(a), Float(b) -> a.CompareTo(b) 
        | _ -> 0 
       | _ -> 0 
+1

이것은 나쁜 생각입니다 ... 컴파일러가 당신에게'GetHashCod e'와'CompareTo'는 equality와 호환되어야한다는 것입니다 (동일한 객체는 동일한 해시 코드를 가져야하며 같은 객체를 비교해야합니다). – kvb

+3

귀하의 유형에서 그것은 두 개의 값이 같음을 비교할 수 있지만 같은 해시 코드를 가질 수없는 것 같습니다. 그게 나 한텐 버그 같아. 개인적으로, 나는 "approxEqualTo"라는 별개의 함수를 만들거나 비슷하게 만들 것이고, 그것을 평등의 핵심 .NET 모델과 혼합하지 않을 것이다. – Grundoon

답변

5

당신은 obj로 DU의 내용을 추출하는 도우미 속성을 정의 할 수 있습니다 조금 느린) 반환 된 객체에 GetHashCode을 호출하는 것입니다 :

override this.GetHashCode() = 
    this.Value.GetHashCode() 
+0

CompareTo와 함께 사용하는 방법이 있습니까? – user2023861

+0

내 의견에 당신을 태그하는 걸 잊어 버렸습니다. – user2023861

+0

@ user2023861 :'box'를'IComparable'에 대한 캐스트로 대체하십시오. – Daniel

관련 문제