如何在F#中调用由参数类型重载的方法?

问题描述 投票:0回答:1

根据通用参数,我正在努力调用由参数类型重载的方法(从C#库中)

在下面的示例中,我使用了带有重载方法的F#类来说明这一点。关键是通用参数可以是struct或引用类型,并且可以是相关参数类型之一的派生类型(我在这里使用了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
c# generics f# overloading
1个回答
0
投票

您可以将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的情况下添加/删除passValueToCorrectMethod时,它可以工作。无论如何,您都会失去编译时的安全性。

© www.soinside.com 2019 - 2024. All rights reserved.