F# F中的反射与模式匹配#

F# F中的反射与模式匹配#,f#,F#,我试图创建F#中给定类型的基元值。代码如下所示,但不起作用。我将感谢所有的帮助和提前感谢 open System let getvalue (t: Type) (v: string) : obj = match box t with | :? int -> let r = (int) v box r | :? byte -> let r = (byte) v box

我试图创建F#中给定类型的基元值。代码如下所示,但不起作用。我将感谢所有的帮助和提前感谢

open System

let getvalue (t: Type) (v: string) : obj =
    match box t with
    | :? int    ->  let r = (int) v
                    box r
    | :? byte   ->  let r = (byte) v
                    box r
    | :? sbyte  ->  let r = (sbyte) v
                    box r
    | :? int16  ->  let r = (int16) v
                    box r
    | :? uint32 ->  let r = (uint32) v
                    box r
    | :? int64 ->   let r = (int64) v
                    box r
    | :? uint64 ->  let r = (uint64) v
                    box r
    | :? double ->  let r = (double) v
                    box r
    | :? float32 -> let r = (float32) v
                    box r
    | :? decimal -> let r = (decimal) v
                    box r
    | :? char ->    let r = (char) v
                    box r
    | :? string -> v :> obj
    | _ -> 
            let s = sprintf "Error unknown type %A" t
            raise (ApplicationException(s))
由于
t
始终是
类型
值,因此它永远不会是
int
字节
十进制
等类型。这就是函数总是引发异常的原因;其他的比赛永远不会是真的

相反,您必须将
t
typeof
typeof
等进行比较。但是,您不能使用常量模式,因为
typeof
typeof
等不是常量

相反,如果..,您可以使用
。。埃利夫。。else
表达式:

open System

let getValue (t: Type) (v: string) : obj =
    if t = typeof<int> then box ((int) v)
    elif t = typeof<byte> then box ((byte) v)
    elif t = typeof<sbyte> then box ((sbyte) v)
    elif t = typeof<int16> then box ((int16) v)
    elif t = typeof<uint32> then box ((uint32) v)
    elif t = typeof<int64> then box ((int64) v)
    elif t = typeof<uint64> then box ((uint64) v)
    elif t = typeof<double> then box ((double) v)
    elif t = typeof<float32> then box ((float32) v)
    elif t = typeof<decimal> then box ((decimal) v)
    elif t = typeof<char> then box ((char) v)
    elif t = typeof<string> then v :> obj
    else 
        let s = sprintf "Error unknown type %A" t
        raise (ApplicationException(s))
开放系统
let getValue(t:Type)(v:string):obj=
如果t=类型,则框((int)v)
elif t=then框的类型((字节)v)
elif t=框的类型((sbyte)v)
elif t=then框的类型((int16)v)
elif t=then框的类型((uint32)v)
elif t=then框的类型((int64)v)
elif t=then框的类型((uint64)v)
elif t=框的类型((双)v)
elif t=then框的类型((浮动32)v)
elif t=then框的类型((十进制)v)
elif t=文本框的类型((字符)v)
elif t=类型,然后v:>obj
其他的
设s=sprintf“错误未知类型%A”t
引发(应用程序异常)

如果你真的想使用模式匹配,你可以考虑把它隐藏在AN后面,但是我个人认为它不值得。

< P>不需要重新创建轮子,使用.< /P> 如果您愿意,那么您可以围绕它编写一个包装器,让编译器自动确定类型

let inline getValue<'a> (s:string) = // limit to string only if desired
  System.Convert.ChangeType(s, typeof<'a>) :?> 'a

let x = getValue "1" + 1.2   // no need to explicitly state "float" anywhere here
printfn "%A" x                    // 2.2
让内联getValue):?>'a
设x=getValue“1”+1.2//此处无需显式声明“float”
printfn“%A”x//2.2

它究竟是如何不起作用的?还有,它是如何使用反射的?它只是不属于任何模式。当你问问题时,千万不要写“它不起作用”。清楚地解释问题和期望的行为