C#项目不尊重F#type` [<NoEquality>]`属性

Yaw*_*war 4 c# f#

我有一个简单的F#类型如下:

(* Num.fsi *)
namespace FsLib

module Num =
  [<NoEquality>]
  type t

  val of_int : int -> t
  val to_int : t -> int
Run Code Online (Sandbox Code Playgroud)

正如您可能想象的那样,实现是微不足道的,它只是一个具有底层证据的单一案例歧视联盟int.现在在同一解决方案的C#项目中,我有以下代码:

// CsTool.cs
using System;
using FsLib;

namespace CsTool {
  class MainClass {
    public static void Main(string[] args) {
      Num.t n1 = Num.of_int(1);
      Num.t n2 = Num.of_int(1);

      Console.WriteLine(n1.Equals(n2));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是,这是打印False而不是无法编译或抛出运行时错误.知道为什么这个C#调用代码忽略了[<NoEquality>]属性?

顺便说一下,我在Mac上的Xamarin Studio社区中运行此版本,版本6.1.2,目标是.NET Framework 4.5.1版.

Ree*_*sey 6

通常,C#语言不会处理许多F#特定功能.从F#使用时,大多数F#类型具有不同的功能.例如,F#类型(默认情况下)无法设置为null,但在C#中,您可以声明并设置它们,null因为C#语言不理解任何F#特定结构.正如您所发现的那样,C#(和其他CLR语言)都忽略了相等和比较保证,可空保证和功能等等.

在实践中,这很少是一个问题,因为大多数人倾向于将F#类型保留在他们的F#代码库中,并从BCL或C#项目中提取类型并将它们转换为F#类型(以添加安全保证)" API边界".

  • @Yawar这是一个非常糟糕的主意.`Object.Equals`的文档说实现必须永远不会抛出异常,结果应该是`true`或`false`. (3认同)
  • @TheInnerLight嗯,我很害怕.好的,那么唯一的解决方案是智能地将其覆盖为我的类型的正确和有意义的相等测试. (3认同)
  • @Yawar一般来说,是的,这是最好的选择 - 除非你想保持引用相等. (3认同)