c# - C# 代码中的模式匹配 F# 类型

标签 c# f# interop

假设有一个F#定义:

type Either<'a,'b> = | Left of 'a | Right of 'b

let f (i : int) : Either<int, string> =
    if i > 0
        then Left i
        else Right "nothing"

函数 fC# 代码中使用:

var a = Library.f(5);

结果值 a 如何为数据构造函数进行模式匹配?像这样的东西:

/*
(if a is Left x)
    do something with x
(if a is Right y)
    do something with y
*/

最佳答案

从 C# 中使用 F# 区分联合有点不雅,因为它们的编译方式。

我认为最好的方法是定义一些成员(在 F# 端),以简化 C# 中类型的使用。有多种选择,但我更喜欢的一种是定义 TryLeftTryRight行为类似于 Int32.TryParse 的方法(因此使用 F# API 的 C# 开发人员应该熟悉它们):

open System.Runtime.InteropServices

type Either<'a,'b> = 
  | Left of 'a 
  | Right of 'b
  member x.TryLeft([<Out>] a:byref<'a>) =
    match x with Left v -> a <- v; true | _ -> false
  member x.TryRight([<Out>] b:byref<'b>) =
    match x with Right v -> b <- v; true | _ -> false

然后您可以使用 C# 中的类型,如下所示:

int a;
string s;
if (v.TryLeft(out a)) Console.WriteLine("Number: {0}", a);
else if (v.TryRight(out s)) Console.WriteLine("String: {0}", s);

这样做会失去一些 F# 安全性,但在没有模式匹配的语言中这是意料之中的。但好处是任何熟悉 .NET 的人都应该能够使用在 F# 中实现的 API。

另一种选择是定义成员 Match这需要 Func<'a>Func<'b>委托(delegate)并使用左/右案例携带的值调用右委托(delegate)。从功能的角度来看,这要好一些,但对于 C# 调用者来说可能不太明显。

关于c# - C# 代码中的模式匹配 F# 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19012155/

相关文章:

c# - Epplus:如何使 "LoadFromCollection"在模型中使用 [DisplayFormat()] 属性

constructor - 构造期间递归访问对象

.net - 通过自托管 wcf 服务从 .net 3.5 调用 .net 4

c# - BindToMoniker 打开一个新的 excel session

c# - Mono C 到正在运行的 C# 程序

c# - 在 CodeBehind 上使用 XAML 样式

c# - 我可以在我的代码中强制使用 `this` 吗?

f# - 如何编写一个 fprintfn 函数,在每次写入时打开、追加、关闭文件,而不会出现 ObjectDisposeException?

f# - F# 中的内联关键字问题

c# - .net 核心中hangfire RecurringJob 的入口点