给定
let inline deserialize<'t> x :'t option =
printfn "Attempting to deserialize %A" typeof<'t>.Name
try
JsonConvert.DeserializeObject<'t>(x)
|> Some
with ex ->
System.Diagnostics.Trace.WriteLine(sprintf "Error deserialization failed:%s" ex.Message)
None
例如,返回obj list
作为null
。 FSharpList<_>
不允许为空。在不知道是什么't
的情况下,我如何询问 F# 我将要返回的类型是否支持 null
,以便我可以相应地停止/抛出/采取行动?是否有反射标志或Microsoft.FSharp.Reflection...
方法?
完整的答案包括检查类型是否为记录(在这种情况下,null
是不允许的(,或者它是否是联合(在这种情况下,如果类型具有标志包含UseNullAsTrueValue
成员的CompilationRepresentation
CustomAttribute
,则允许 null(https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/core.compilationrepresentationflags-enumeration-%5Bfsharp%5D 更多详细信息((。
要回答第一个问题,您可以使用FSharpType
模块 (https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/reflection.fsharptype-class-%5Bfsharp%5D( 中的 IsRecord
函数,要回答第二个问题,您可以使用同一模块上的 IsUnion
函数和CustomAttribute
搜寻的组合。
如果类型是带有UseNullAsTrueValue
集合的联合,您应该很高兴,只需发送值即可。
我能想到的最好的方法是将结果装箱(以防您正在反序列化结构(并将其与 null 匹配:
let inline deserialize<'t> x :'t option =
printfn "Attempting to deserialize %A" typeof<'t>.Name
try
let obj = Newtonsoft.Json.JsonConvert.DeserializeObject<'t>(x)
match box obj with
| null -> None
| _ -> Some obj
with ex ->
System.Diagnostics.Trace.WriteLine(sprintf "Error deserialization failed:%s" ex.Message)
None
let r1 = deserialize<obj list> ("[1,2,3]") //val r1 : obj list option = Some [1L; 2L; 3L]
let r2 = deserialize<obj list> ("null") //val r2 : obj list option = None