我有一个简单的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版.
通常,C#语言不会处理许多F#特定功能.从F#使用时,大多数F#类型具有不同的功能.例如,F#类型(默认情况下)无法设置为null,但在C#中,您可以声明并设置它们,null因为C#语言不理解任何F#特定结构.正如您所发现的那样,C#(和其他CLR语言)都忽略了相等和比较保证,可空保证和功能等等.
在实践中,这很少是一个问题,因为大多数人倾向于将F#类型保留在他们的F#代码库中,并从BCL或C#项目中提取类型并将它们转换为F#类型(以添加安全保证)" API边界".