假设有一个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"
函数 f
在 C#
代码中使用:
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# 中类型的使用。有多种选择,但我更喜欢的一种是定义 TryLeft
和 TryRight
行为类似于 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/