使用 F# Reflection 比较具有默认 IComparable 实现的两个对象
Comparing two objects with default IComparable implementation with F# Reflection
给定 F# 中的两个对象,有没有一种方法可以使用它们的 IComparable 方法来比较它们,假设它们都是相同的子类型并且 IComparable 是为它们的公共子类型实现的。
我想用伪代码实现什么:
let tycompare (o1 : obj) (o2 : obj) : int option =
let (ty1, ty2) = (o1.GetType(), o2.GetType())
if ty1 <> ty2 then
None
else
if IComparable is implemented on ty1 then
o1.CompareTo(o2) |> Some
else
None
我知道这个 post 但我不认为它有助于直接回答我的问题。
你也可以用 Option.bind
写得更简洁,但这非常适合模式匹配。
我们可以定义一个active pattern来匹配IComparable
.
let (|IsComparable|) (obj : obj) =
match obj with
| :? IComparable as comparable -> Some(comparable)
| _ -> None
F# 允许您在 let
绑定中使用活动模式,以便更清楚地传达函数的意图。
let compare (IsComparable o1) (IsComparable o2) =
match (o1, o2) with
| (Some o1, Some o2) when
o1.GetType() = o2.GetType() -> Some(o1.CompareTo(o2))
| _ -> None
这也可以压缩(没有活动模式 - @kaefer):
let compare (o1 : obj) (o2: obj) =
match (o1, o2 ) with
| (:? System.IComparable as o1), (:? System.IComparable as o2) when
o1.GetType() = o2.GetType() -> Some(o1.CompareTo(o2))
| _ -> None
给定 F# 中的两个对象,有没有一种方法可以使用它们的 IComparable 方法来比较它们,假设它们都是相同的子类型并且 IComparable 是为它们的公共子类型实现的。
我想用伪代码实现什么:
let tycompare (o1 : obj) (o2 : obj) : int option =
let (ty1, ty2) = (o1.GetType(), o2.GetType())
if ty1 <> ty2 then
None
else
if IComparable is implemented on ty1 then
o1.CompareTo(o2) |> Some
else
None
我知道这个 post 但我不认为它有助于直接回答我的问题。
你也可以用 Option.bind
写得更简洁,但这非常适合模式匹配。
我们可以定义一个active pattern来匹配IComparable
.
let (|IsComparable|) (obj : obj) =
match obj with
| :? IComparable as comparable -> Some(comparable)
| _ -> None
F# 允许您在 let
绑定中使用活动模式,以便更清楚地传达函数的意图。
let compare (IsComparable o1) (IsComparable o2) =
match (o1, o2) with
| (Some o1, Some o2) when
o1.GetType() = o2.GetType() -> Some(o1.CompareTo(o2))
| _ -> None
这也可以压缩(没有活动模式 - @kaefer):
let compare (o1 : obj) (o2: obj) =
match (o1, o2 ) with
| (:? System.IComparable as o1), (:? System.IComparable as o2) when
o1.GetType() = o2.GetType() -> Some(o1.CompareTo(o2))
| _ -> None