我有一个这样的记录类型:
type Node<'T> = { doStuff: 'T -> unit ; id: int }
如何实现相等/可比,以便仅等同/比较 id?
注意:这需要在不同类型的节点之间工作。所以等同/比较Node<int>
和Node<string>
.当涉及泛型时,这似乎并不微不足道。
它可以通过一个通用的基本类型来完成:
type IHaveId =
abstract Id : int
inherit System.IComparable
type [<CustomEquality; CustomComparison>] Node<'T> =
{ DoStuff: 'T -> unit ; Id: int }
interface IHaveId with
member n.Id = n.Id
override n.Equals n' =
match n' with
| :? IHaveId as n' -> n.Id = n'.Id
| _ -> invalidArg "n'" "Tried to equate incompatible types."
override n.GetHashCode () = n.Id.GetHashCode()
interface System.IComparable with
member n.CompareTo n' =
match n' with
| :? IHaveId as n' -> n.Id.CompareTo n'.Id
| _ -> invalidArg "n'" "Tried to compare incompatible types."
请注意,这不是很快。另外,要小心:随着公共建设访问Node<'T>
,可以构建做不同事情但被视为平等的节点。
使用接口进行DoStuff
将允许结构比较。如果对象及其 ID 是集中构造的,我会考虑[<ReferenceEquality>]
并将比较函数显式传递给需要它的集合(例如 Set<_>
或 Map<_>
)。
我猜为该类型编写静态成员将是某种解决方案
static member compareNodes (n1:Node<_>) (n2:Node<_>) =
n1.id.CompareTo(n2.id)