如何在带有静态解析类型参数的F#类型中实现自定义相等方法?
我尝试过这种方式:
[<CustomEqualityAttribute>]
type Fraction< ^a when ^a: equality and ^a : (static member (*): ^a * ^a -> ^a) > (nominator: ^a, denominator: ^a) =
member inline this.Nominator = nominator
member inline this.Denominator = denominator
member inline this.IsEqualTo(other: Fraction< ^a >) = this.Nominator * other.Denominator = other.Nominator * this.Denominator
override inline this.Equals(other: obj) =
match obj with
| :? Fraction< ^a > as f -> this.IsEqualTo(f)
| _ -> false
我在this.Equals
行上收到以下错误:
此成员,函数或值声明不得声明为“内联”
那是为什么?是因为Equals
是替代项吗?如果是这样,有什么办法可以实现自定义相等性,还是我不得不使用IEqualityComparer
?
答案 0 :(得分:3)
那是为什么?是因为
Equals
是优先选项吗?
是的。类的inline
方法不是该类的 actual 方法。相反,在某个地方对该方法的每次调用都将被解释为其实现(非常类似于C ++)。由于您要覆盖Equals
类中的实际方法Object
,因此无法将其设为inline
。
如果是这样,有什么办法可以实现自定义相等性?
您可以从类型中提取具体乘法,因此不会强制inline
方法使用Equals
:
[<CustomEquality; NoComparison>]
type Frac<'T when 'T : equality> = private {
nominator : 'T
denominator : 'T
mult : 'T -> 'T -> 'T
} with
member x.Nominator = x.nominator
member x.Denominator = x.denominator
override x.Equals other =
match other with
| :? Frac<'T> as o ->
let ( * ) = x.mult in x.nominator * o.denominator = o.nominator * x.denominator
| _ -> false
static member inline Create x y = { nominator = x; denominator = y; mult = ( * ) }
// Test
Frac.Create 1 2 = Frac.Create 3 6 // true
Frac.Create 1.0 2.0 = Frac.Create 3.0 7.0 // false
Frac.Create 1 2 = Frac.Create 3.0 6.0 // compile error