将F#列表设置为空以便序列化

将F#列表设置为空以便序列化,f#,json.net,F#,Json.net,我在使用JSON.NET库的JSON数据存储旁边使用F#。我试图在可能的情况下利用F#结构和类型,并遇到了以下问题。假设我希望存储以下数据结构 type A = { id : int name : string posts : string list } 创建工作正常,但要仅更新存储的名称字段,我需要发送一条JSON记录,其中省略posts字段。使用空列表不起作用,因为持久性系统会假设我希望用空列表替换现有的帖子,从而覆盖它们。从“我已经读到”中,可以通过将字段设置为n

我在使用JSON.NET库的JSON数据存储旁边使用F#。我试图在可能的情况下利用F#结构和类型,并遇到了以下问题。假设我希望存储以下数据结构

type A = {
    id : int
    name : string
    posts : string list
}
创建工作正常,但要仅更新存储的
名称
字段,我需要发送一条JSON记录,其中省略
posts
字段。使用空列表不起作用,因为持久性系统会假设我希望用空列表替换现有的帖子,从而覆盖它们。从“我已经读到”中,可以通过将字段设置为
null
,将其从序列化中省略

let updatedEntry = { id : 0, name : "Fred", posts = null }

但是,F#编译器将给出一个错误,说明类型
列表
不能设置为
null
。在F#中是否有实现这一点的方法,也许这是一个我不知道的属性?谢谢

有两种方法可以轻松做到这一点:

选择1 使用System.Collections.Generic.List类型,该类型可以为空:

> type A = {id: int; name:string; posts: System.Collections.Generic.List<string> };;

type A =
  {id: int;
   name: string;
   posts: System.Collections.Generic.List<string>;}

> let a = {id=5; name="hello"; posts=null};;

val a : A = {id = 5;
             name = "hello";
             posts = null;}
请注意,您需要将
posts
成员与
None
进行比较,而不是将
null
进行比较

方便阅读:


编辑

(经过一些搜索和实验后)您可以使用boxing来仍然使用F#types作为值:

> type A = {id: int; name:string; posts: System.Object };;

type A =
  {id: int;
   name: string;
   posts: Object;}

> let a = {id=5; name="foo"; posts=null};;

val a : A = {id = 5;
             name = "foo";
             posts = null;}

> let b = {id=6; name="bar"; posts=(box [])};;

val b : A = {id = 6;
             name = "bar";
             posts = [];}

但我个人还是选择选项类型

谢谢你的回复。是的,这是我正在考虑的两种方法。虽然我很想留在F#生态系统中,但一般的.NET列表类型仍然有效。使用选项类型当然更为惯用,可能也是我将要采用的方式——我只是想看看是否可以使用
null
来“逃脱”,因为它只在持久性层中需要。干杯。在我看来,当我阅读你的问题时,可能有一个属性允许空值,但我只想给出“适当”选项作为答案:)有
AllowNullLiteral
属性,但我在记录字段上尝试了该属性,它给了我一个“此属性对于此语言元素无效”错误。也许有一个不同的属性可以工作?再看一看,这似乎是不可能的。多有趣啊,我需要读更多关于“拳击”的书。但是,是的,正如您所建议的,我将坚持使用选项类型,因为它将使代码的含义更加明确,并且是“正确”的方式:)。谢谢。@mands我忘记了拳击,直到我在寻找更多关于拳击的信息时看到它,然后我回忆起曾经读过它。(这一定给人留下了深刻的印象!)很高兴我能帮上忙:)@mands注意,如果使用
ResizeArray
类型别名而不是
System.Collections.Generic.List
,则可以避免一些键入。
> type A = {id: int; name:string; posts: System.Object };;

type A =
  {id: int;
   name: string;
   posts: Object;}

> let a = {id=5; name="foo"; posts=null};;

val a : A = {id = 5;
             name = "foo";
             posts = null;}

> let b = {id=6; name="bar"; posts=(box [])};;

val b : A = {id = 6;
             name = "bar";
             posts = [];}