将F#列表设置为空以便序列化
我在使用JSON.NET库的JSON数据存储旁边使用F#。我试图在可能的情况下利用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
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 = [];}