当编译器坚持认为不可能时,如何从 Newtonsoft 检查 `null`?
How to check for `null` from Newtonsoft when the compiler insists that it isn't possible?
我们的项目混合了 C# 和 F# 以及 ASP.NET 核心。 ASP.NET 到处都是 serializing/deserializing 的核心默认为 Newtonsoft,并且 swagger 文档生成 (nswag) 也依赖于类似 CLI(可变)的 DTO 来生成正确的类型。
我们的 DTO 在 F# 中定义如下:
[<CLIMutable>]
type Query =
{ Status: string
Offset: int
Limit: int }
这使得 Newtonsoft 序列化和 nswag 生成 swagger 文档变得微不足道。
但是..!我在 null/option "mismatch" 上遇到了非常困难的时期。 C#/Newtonsoft/NSwag坚持用null
,不会看懂F#的option
。所以在我的 F# 中,我 有 检查空值并将它们转换为选项;并在从域转换回 DTO 时将我的选项转换回空值。
但是 F# 坚持 null 是不可能的,以至于我什至不允许检查:编译器给我:"The type {...} does not have 'null' as a proper value"。但事实是 runtime,它 IS null 因为这就是 Newtonsoft 的工作方式。 Newtonsoft 似乎是 .NET 标准,所以不幸的是,我认为使用其他东西不可行。
即使 F# 认为它不可能为空,我如何检查空值?
解决这个问题的一个简单方法(通常)是在检查 null 之前将值装箱。
let isReallyNull value = value |> box |> isNull
然后你可以按照你的正常逻辑查看Newtonsoft返回的对象实例:
if dto |> isReallyNull
then None
else Some dto
这是一个完整的示例,使用 Unchecked.defaultof
为编译器认为不能为 null 的类型生成 null 值:
[<CLIMutable>]
type MyDto =
{
Status: string
Offset: int
Limit: int
}
let isReallyNull value = value |> box |> isNull
let dto = Unchecked.defaultof<MyDto>
// if dto |> isNull (* Compiler complains that MyDto does not have null as a proper value *)
if dto |> isReallyNull
then printfn "The DTO is null"
else printfn "The DTO is non-null"
let optionalValue = Option.ofObj dto
正如 Aaron 所建议的,如果 dto 是记录类型,那么您需要这样做:
let optionalValue = dto |> box |> Option.ofObj
我们的项目混合了 C# 和 F# 以及 ASP.NET 核心。 ASP.NET 到处都是 serializing/deserializing 的核心默认为 Newtonsoft,并且 swagger 文档生成 (nswag) 也依赖于类似 CLI(可变)的 DTO 来生成正确的类型。
我们的 DTO 在 F# 中定义如下:
[<CLIMutable>]
type Query =
{ Status: string
Offset: int
Limit: int }
这使得 Newtonsoft 序列化和 nswag 生成 swagger 文档变得微不足道。
但是..!我在 null/option "mismatch" 上遇到了非常困难的时期。 C#/Newtonsoft/NSwag坚持用null
,不会看懂F#的option
。所以在我的 F# 中,我 有 检查空值并将它们转换为选项;并在从域转换回 DTO 时将我的选项转换回空值。
但是 F# 坚持 null 是不可能的,以至于我什至不允许检查:编译器给我:"The type {...} does not have 'null' as a proper value"。但事实是 runtime,它 IS null 因为这就是 Newtonsoft 的工作方式。 Newtonsoft 似乎是 .NET 标准,所以不幸的是,我认为使用其他东西不可行。
即使 F# 认为它不可能为空,我如何检查空值?
解决这个问题的一个简单方法(通常)是在检查 null 之前将值装箱。
let isReallyNull value = value |> box |> isNull
然后你可以按照你的正常逻辑查看Newtonsoft返回的对象实例:
if dto |> isReallyNull
then None
else Some dto
这是一个完整的示例,使用 Unchecked.defaultof
为编译器认为不能为 null 的类型生成 null 值:
[<CLIMutable>]
type MyDto =
{
Status: string
Offset: int
Limit: int
}
let isReallyNull value = value |> box |> isNull
let dto = Unchecked.defaultof<MyDto>
// if dto |> isNull (* Compiler complains that MyDto does not have null as a proper value *)
if dto |> isReallyNull
then printfn "The DTO is null"
else printfn "The DTO is non-null"
let optionalValue = Option.ofObj dto
正如 Aaron 所建议的,如果 dto 是记录类型,那么您需要这样做:
let optionalValue = dto |> box |> Option.ofObj