【发布时间】:2017-02-01 15:34:10
【问题描述】:
在我看来,F# 选项类型的某些属性在 C# 项目中是不可见的。通过检查类型,我或多或少可以看出原因,但我并不真正了解究竟发生了什么,为什么做出这些选择或如何最好地规避问题。
这里有一些 sn-ps 演示了这个问题。我有一个 VS2015 解决方案,其中包含两个项目,一个 C# 项目和一个 F# 项目。在 F# 项目中,我有一个类定义如下:
type Foo () =
member this.Bar () = Some(1)
此外,在 F# 中我可以这样写:
let option = (new Foo()).Bar()
let result = if option.IsNone then "Is none" else "Is some"
所以看起来选项类型有一个名为IsNone 的属性。现在,在 C# 项目中,我引用了从 F# 项目编译的 .dll。这让我可以写例如
var optionType = new Foo().Bar();
变量optionType 是FSharpOption<int>。如上所述,当我在 F# 项目中使用选项类型时,我通常可以访问例如 IsSome 和 IsNone 属性。但是,当我尝试编写 optionType.IsNone 之类的内容时,我收到 CS1546 错误“语言不支持属性、索引器或事件 ...”。与此一致,Intellisense 不会检测到该属性:
现在,在检查 FSharpOption 类型时,我可以看到 IsNone 和 IsSome “属性”显示为静态方法:
另一方面,当我从 F# 检查类型时,我看到的是以下内容:
在这里,属性IsSome 和IsNone 的“存在”是显而易见的。将光标悬停在这些属性上,VS2015 给了我以下注释:“包含类型可以使用 'null' 作为其空联合情况的表示值。该成员将被编译为静态成员。”这就是为什么这些属性除了作为静态方法之外不可用的原因(正如 lukegv 和 Fyodor Soikin 所指出的那样)。
因此,情况似乎如下:编译后的 FSharpOption 类型没有任何 IsNone 和 IsSome 属性。 F# 的幕后正在发生一些事情,以启用模拟这些属性的功能。
我知道我可以通过在 Microsoft.FSharp.Core 中使用 OptionModule 来解决这个问题。然而,这个功能似乎是 F# 核心库的架构师有意识的选择。选择的原因是什么?并且使用 OptionModule 是正确的解决方案,还是有更好的方法来使用 C# 中的 FSharpOption<T> 类型?
【问题讨论】:
标签: c# properties f# interop