动态获取Option类型存在一些困难.假设我有一个功能:
let printType x =
if (box x) = null then printfn "the type is 'null'"
else printfn "the type is %A" (x.GetType())
Run Code Online (Sandbox Code Playgroud)
我们在这里有输出:
printType 3 // the type is System.Int32
printType (Some(3)) // the type is Microsoft.FSharp.Core.FSharpOption`1[System.Int32]
printType None // the type is null
printType null // the type is null
Run Code Online (Sandbox Code Playgroud)
获取表达式的类型时,如何区分None和null?
在运行时,选项None值表示为null,因此您无法确定其运行时类型.但是,您可以编写一个通用函数来打印选项的静态类型:
let printType (x:'T option) =
printfn "Static type is: %s" (typeof<'T>.Name)
Run Code Online (Sandbox Code Playgroud)
根据您的需要,这可能会或可能不会满足您的需求.
printType (None : int option) // Int32
printType (None : string option) // String
printType None // Object (the default used by the inference)
Run Code Online (Sandbox Code Playgroud)
编辑如果你想能够在任何参数上调用函数,你可以 typeof<'T>像我的例子中一样使用Matthew的解决方案中的其余逻辑.以下内容与Matthew的代码片段完全相同(但它没有正当理由创建引号):
let printType (x:'T) =
let typeOfX = typeof<'T>
if not <| FSharpType.IsUnion(typeOfX) && (box x) = null then
printfn "Static type is %s, but the value is 'null'" typeOfX.Name
else
printfn "Static type is %s and value is not 'null'" typeOfX.Name
Run Code Online (Sandbox Code Playgroud)
编辑: 不需要代码引用,可以使用 typeof 代替,请参阅@Tomas Petricek的答案
您可以使用代码引用从 None 获取类型
open Microsoft.FSharp.Reflection
let printType x =
let typeOfX = <@ x @>.Type
if not <| FSharpType.IsUnion(typeOfX) && (box x) = null then
printfn "the type is 'null'"
else
printfn "the type is %A" typeOfX
Run Code Online (Sandbox Code Playgroud)
您的输入:
printType 3 // the type is System.Int32
printType (Some(3)) // the type is Microsoft.FSharp.Core.FSharpOption`1[System.Int32]
printType None // the type is Microsoft.FSharp.Core.FSharpOption`1[System.Object]
printType null // the type is 'null'
Run Code Online (Sandbox Code Playgroud)