This question already has answers here:
Testing for null reference in F#

(3 个回答)


2年前关闭。




我们的项目将 C# 和 F# 与 ASP.NET Core 混合在一起。 ASP.NET 核心默认使用 Newtonsoft 进行任何地方的序列化/反序列化,并且 swagger 文档生成 (nswag) 也依赖于 CLI(Mutable) 之类的 DTO 来生成正确的类型。

我们的 DTO 在 F# 中定义如下:
[<CLIMutable>]
type Query =
    { Status: string
      Offset: int
      Limit: int }

这使得 Newtonsoft 序列化和 nswag 生成 swagger 文档变得微不足道。

但..!我对空/选项“不匹配”感到非常困难。 C#/Newtonsoft/NSwag 坚持使用 null ,不会理解 F# 的 option 。所以在我的 F# 中,我必须检查空值并将它们转换为选项;并在从域转换回 DTO 时将我的选项转换回空值。

但是 F# 坚持认为 null 不可能达到我什至不允许检查的地步:编译器给了我:“类型 {...} 没有将 'null' 作为正确值”。但事实是运行时,它是空的,因为 Newtonsoft 就是这样工作的。 Newtonsoft 似乎是 .NET 标准,所以不幸的是,我认为使用其他东西是不可行的。

即使 F# 认为它不可能为空,我如何检查空值?

最佳答案

克服这个问题的一个简单方法(通常)是在检查空值之前将值装箱。
let isReallyNull value = value |> box |> isNull
然后你可以在你的正常逻辑中检查 Newtonsoft 返回的对象实例:

if dto |> isReallyNull
then None
else Some dto

这是一个完整的示例,使用 Unchecked.defaultof 为编译器认为不能为空的类型生成空值:
[<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"

关于.net - 当编译器坚持认为不可能时,如何从 Newtonsoft 检查 `null`?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56257157/

10-11 02:55