У меня есть простое размеченное объединение F #, которое объединяет логическое значение, строку и число с плавающей запятой. Я хочу переопределить Object.Equals (arg) этого объединения, чтобы я мог добавить эпсилон для учета ошибок точности при проверке равенства с плавающей запятой. Компилятор жаловался, что если я переопределю this.Equals (arg), я также должен переопределить this.GetHashCode () и this.CompareTo (arg). Для их переопределения я не планирую никаких специальных функций, поэтому я просто хотел бы вызвать версии этих методов по умолчанию. В моей реализации сейчас у меня есть три вызова GetHashCode и три вызова CompareTo для каждого типа в моем размеченном объединении: по одному для каждого типа.
Есть ли способ закодировать переопределение GetHashCode с помощью всего одного вызова GetHashCode? Тот же вопрос для CompareTo? Все типы в моем размеченном объединении реализуют ICompareable.
[<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
GetHashCode
иCompareTo
, заключается в том, что они должны быть совместимы с равенством (одинаковые объекты должны иметь одинаковые хэш-коды и должны сравниваться). - person kvb   schedule 09.12.2014