F#中的联合类型和其他基本类型默认使用结构相等,并提供了一个生成的 .Equals 方法覆盖。F#相等运算符显然与C#不同,即使对于引用类型也使用 .Equals 方法,但是当从C#中使用F#联合类型时,默认的对象operator==会被使用,它检查引用相等而不是结构相等。
为什么F#不为联合类型生成自定义operator==,以便在其他.NET语言中使用==时获得预期的行为?
为什么F#不为联合类型生成自定义operator==,以便在其他.NET语言中使用==时获得预期的行为?
我不在F#团队中,所以我只能猜测,但以下是一些可能的原因:
Equals
方法。C#提供了测试两种不同类型的相等性的方法——为什么F#要强制它们以相同的方式行事,而有些人可能更喜欢使用引用相等性呢?如果你想强制C#使用结构相等性,那么自己实现也很容易:
type T = A | B of int with
static member op_Equality(t:T,t2:T) = t = t2
// or even static member (=)(t:T, t2:T) = t = t2
任何功能都有开发成本,因此即使自动生成op_Equality
有明显的好处,也可能会被放弃以支持更高优先级的功能。
这种行为是由您使用的语言而不是您使用的类型的原始语言定义的。
==
操作符是 C# 的东西。它们使用不同的名称 (=
vs ==
),正是因为它们执行不同的操作,并且这来自 OCaml 继承而来。 - J D(+)
被翻译为 op_Addition
,这是 C# 可以识别的)。他们同样可以轻易地生成一个 op_Equality
方法。 - kvbtype T() = static member (+)(_:T,_:T) = T()
,那么你也应该能够在 C# 中对 T
的实例使用 +
运算符。这是因为 F# 编译形式会创建一个名为 op_Addition
的静态方法,这也是 C# 重载 +
运算符的方式。 - kvb
Object.ReferenceEquals
只是调用了==
。 - Joel Mueller==
运算符的行为方式——很容易错误地退回到引用相等性。我认为使用Equals
几乎总是更好的选择,对于 F# 类型也可以正常工作。 - kvb