6

私は使用Microsoft.FSharp.Reflection.FSharpValue.MakeUnionしていますが、これには aReflection.UnionCaseInfoと an obj[](空にすることもできます) がパラメーターとして必要です。

ただし、 Type mismatch. Expecting a obj [] but given a string [] The type 'obj' does not match the type 'string'である関数の結果で呼び出すと、が取得されstring[]ます。

私が作成できる最も簡単な例は次のとおりです (これをラップしたテストがありますが、 とマークされた行のためにコンパイルされません!!

let one (a:obj[]) = a |> Array.map (fun o->printfn "%A" o) |> ignore
one [|"a";"b";"c"|] // OK!
let str = [|"a";"b";"c"|] //the equivalent of my function return
one str//!!Type mismatch.

string[] を obj[] にキャスト/変換するつもりなのか、それとも ... まあ、私が知らない他の何か間違ったことをしているだけなのかどうかはわかりません。

編集:実際の問題は以下のとおりです

let split (by:string) (input:string) = System.Text.RegularExpressions.Regex.Split(input,by)

let buildArgs content = 
 match content with
 | "" -> [||]
 | _ -> content |> split " " //Type mismatch

これは私が解決するために使用したものです:より良い方法はありますか?

 | _ -> content |> split " "|> Array.map (fun s->s:>obj)//make sure obj[] is returned

参照としてのキャストと変換 (F#)

私もこれを試しました

let buildArgs content :obj[] = ... // Type mismatch

しかし、それも私にエラーを与えます:

を行わない場合は、関数の最後の行に Mismatch と入力しますArray.map

4

2 に答える 2

5

あなたの現在のアプローチは問題ないと思います。[|for str in ... -> box str|]よりも少し読みやすいようなものを見つけること... |> Array.map (fun str -> box str)がありますが、マイレージは異なる場合があります。なぜこれに遭遇するのかというと、ここにはやや微妙な問題が 2 つあります。

Phil Trelford のコメントが暗示しているように、.NET 型システムではstring[]として扱うことができますobj[](.NET 型システムはそれほど厳密ではありませんが、F# からこれを行うにはアップキャストとダウンキャストが必要です)。私の意見では、この型システムの「機能」は忌まわしいものであり、この場合はおそらく安全ですが、一般的には避けたいと思います (配列共分散の望ましくないことに関する意見の一致については、C# の共分散と反分散、パート 2: 配列共分散配列の共分散: 醜いだけでなく、遅い)。

したがって、一般に、コンパイラは astring[]を an として扱いません。obj[]では、なぜあなたが合格したときにすべてがうまくいくの[|"a"; "b"; "c"|]ですか? ここでの答えは、配列リテラルの特定のケースでは、そのようなスーパータイプが推論できる場合、コンパイラは配列式のタ​​イプを各要素のタイプのスーパータイプにすることを許可します (たとえばobj[]、別のメソッドのシグネチャによって制約されているため)。あなたの場合)。ただし、これは配列リテラル(つまり、形式の式[|e1; e2; ... |]) の場合にのみ機能します。

于 2013-08-18T20:14:36.090 に答える