나는 부울, 문자열 및 부동 소수점을 결합한 간단한 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
이것은 나쁜 생각입니다 ... 컴파일러가 당신에게'GetHashCod e'와'CompareTo'는 equality와 호환되어야한다는 것입니다 (동일한 객체는 동일한 해시 코드를 가져야하며 같은 객체를 비교해야합니다). – kvb
귀하의 유형에서 그것은 두 개의 값이 같음을 비교할 수 있지만 같은 해시 코드를 가질 수없는 것 같습니다. 그게 나 한텐 버그 같아. 개인적으로, 나는 "approxEqualTo"라는 별개의 함수를 만들거나 비슷하게 만들 것이고, 그것을 평등의 핵심 .NET 모델과 혼합하지 않을 것이다. – Grundoon