ジェネリックパラメーターに従って、パラメータータイプによってオーバーロードされたメソッド(C#ライブラリから)を呼び出すのに苦労しています
次の例では、ポイントを説明するために、代わりにオーバーロードされたメソッドを持つF#クラスを使用しました。ジェネリックパラメーターがastruct
または参照型のいずれかであり、関連するパラメーター型の1つの派生型であることが重要です(StreamWriter
ここではそれを説明するために使用しました)。
open System.IO
type MyClass() =
member this.Method(n: int) = sprintf "Integer %i" n
member this.Method(s: string) = sprintf "String %s" s
member this.Method(w: TextWriter) = sprintf "Some kind of text writer"
let passValueToCorrectMethod (c: MyClass) (value: 'a) : string =
match value with
| :? int as n -> c.Method(n) // ERROR: Runtime type tests are not allowed on some types
| :? string as s -> c.Method(s)
| :? TextWriter as w -> c.Method(w)
// what I want to be able to do with it
let c = MyClass()
let sw = new StreamWriter("C:\temp\blah")
let result1 = passValueToCorrectMethod c 5
let result2 = passValueToCorrectMethod c "hi"
let result3 = passValueToCorrectMethod c sw
(@Charles Magerによって提案されているように)に変更value: 'a
しvalue: obj
、オプションでキャッチオールケースを追加できます_ -> failwith "No overload"
。または、リフレクションを使用する場合:
let passValueToCorrectMethod (c: MyClass) (value: 'a) : string =
let valueType = typeof<'a>
let mi = c.GetType().GetMethod("Method", BindingFlags.Instance ||| BindingFlags.Public, null, [| valueType |], null)
if isNull mi then
failwithf "No overload for %s" valueType.Name
else
mi.Invoke(c, [| value |]) |> string
// what you'll be able to do with it
let c = MyClass()
let sw = new StreamWriter(".\\temp.txt")
passValueToCorrectMethod c sw // Some kind of text writer
passValueToCorrectMethod c () // Runtime Exception: No overload for Unit
このようにMethod
、を変更せずにsを追加/削除するときに機能しpassValueToCorrectMethod
ます。とにかく、コンパイル時の安全性が失われます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加