1

F#で関数を作成しました

let tryParseArray tryParse (separator:char) (line: string) =
    // inside the function I use the tuple form of tryParse

私がそのようにそれを呼ぶならば、それはうまく働きます:tryParseArray Int32.TryParse ',' "2,3,2,3,2"

この関数をC#でも使用できるようにしたいので、次のようにしました。

static member TryParseArray (line, tryParse, separator) =
    line |> tryParseArray tryParse separator

TryParseArrayそれから私はそれが実際にtryParse引数をとることに気づきましたFSharpFunc、それはC#に全く友好的ではないので、私はこれを試しました:

static member TryParseArray (line, [<Out>] tryParse: (string * byref<'a> -> bool), separator) =
    line |> tryParseArray tryParse separator

しかし、現在は有効な引数としてtryParseArray受け入れられません(タイプエラー)tryParse

私は何をすべきか?

C#で電話TryParseArray("2,3,2,3,2", Int32.TryParse, ',')もできるといいのですが

4

2 に答える 2

5

カスタムデリゲートタイプを使用して、この関数をC#に公開できます。

編集済み

// 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, ',');

注:C#側では、TryParseの型パラメーターを明示的に指定する必要があります(匿名デリゲート/ラムダがout / refパラメーターの型を推測しないのはなぜですか?

于 2013-01-25T01:37:37.673 に答える
0

descoのソリューションは優れていますが、回避したい場合は、byref次のようなことを行うことができます。

type TryParse<'R>  = delegate of string -> bool * 'R

module Util =
  [<CompiledName("TryParseArray")>]
  let tryParseArray (tryParse: TryParse<_>) (separator:char) (line: string) = ...

これは、次のようにF#から呼び出すことができます。

let res = Util.tryParseArray (TryParse(Int32.TryParse)) ',' "1,2,3"

そして、次のラッパーメソッドを使用します。

static class TryParse {
    public static Tuple<bool, int> Int32(string s) {
        int i;
        var b = System.Int32.TryParse(s, out i);
        return Tuple.Create(b, i);
    }
}

このように、C#から:

var res = Util.TryParseArray(TryParse.Int32, ',', "1,2,3");
于 2013-01-25T16:15:04.843 に答える