我有这样的记录类型:
type Node<'T> = { doStuff: 'T -> unit ; id: int }
如何实现相等/可比,以便只将id等同/比较?
注意:这需要在不同类型的节点之间工作。因此,等同/比较Node<int>
和Node<string>
。当涉及仿制药时,这似乎并不重要。
答案 0 :(得分:2)
可以通过一个共同的基本类型来完成:
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<_>
)。
答案 1 :(得分:1)
我猜想为该类型编写静态成员将是一些解决方案
static member compareNodes (n1:Node<_>) (n2:Node<_>) =
n1.id.CompareTo(n2.id)