我在F#中创建了一个函数
let tryParseArray tryParse (separator:char) (line: string) =
// inside the function I use the tuple form of tryParse
Run Code Online (Sandbox Code Playgroud)
如果我以这种方式调用它,它工作正常: tryParseArray Int32.TryParse ',' "2,3,2,3,2"
现在我希望这个函数也可以在C#中使用,所以我这样做了:
static member TryParseArray (line, tryParse, separator) =
line |> tryParseArray tryParse separator
Run Code Online (Sandbox Code Playgroud)
然后我意识到TryParseArray实际上把tryParse参数作为FSharpFunc,对C#一点都不友好,所以我尝试了这个:
static member TryParseArray (line, [<Out>] tryParse: (string * byref<'a> -> bool), separator) =
line |> tryParseArray tryParse separator
Run Code Online (Sandbox Code Playgroud)
但现在tryParseArray不接受tryParse作为有效参数(类型错误)
我该怎么办?
我想在C#中我可以调用TryParseArray("2,3,2,3,2", Int32.TryParse, ',')以及
您可以使用自定义委托类型将此函数公开给C#:
EDITED
// F#
module Lib
let tryParseArray parser (line : string) (sep : char) =
// don't know your exact implementation so again just guessing...
line.Split sep
|> Array.choose (fun el ->
match parser el with
| true, el -> Some el
| false, _ -> None
)
open System.Runtime.InteropServices
type TryParse<'R> = delegate of str : string * [<Out>] res : byref<'R> -> bool
type T =
static member TryParse(line : string, tryParse : TryParse<'R>, separator : char) : 'R[] =
tryParseArray tryParse.Invoke line separator
//C#
var r = Lib.T.TryParse<int>("1,2,3", int.TryParse, ',');
Run Code Online (Sandbox Code Playgroud)
注意:在C#端你需要明确指定TryParse的类型参数(为什么匿名委托/ lambdas不在out/ref参数上推断类型?)