Set F # list to null for serialization

I am using F # alongside a JSON data store using the JSON.NET library. I am trying to use F # structs and types where possible and am faced with the following problem. Let's say I want to keep the following data structure,

type A = {
    id : int
    name : string
    posts : string list
}

      

Creation works fine, but to update only the saved field, name

I need to send a JSON record that did not specify the field posts

. Using an empty list will not work because the save system will assume that I want to replace existing entries with an empty list and thus overwrite them. From JSON.NET docs I read a field that can be excluded from serialization by setting it to null

,

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

      

However, the F # compiler will throw an error stating that the type list

cannot be set to null

. Is there a way to do this from within F #, possibly with an attribute that I am not aware of? Thanks to

+3


source to share


1 answer


There are two ways to do this easily:

Option 1

Use the System.Collections.Generic.List type, which can be null:

> 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;}

      

Option 2

Another, more idiomatic way would be to use the Option type:

> type A = {id: int; name:string; posts: string list option };;

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

> let a = {id=5; name="there"; posts=None};;

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

      



Note that you are comparing the element posts

with None

, not null

.

Convenient Reading: Option Types


Edit

(After some searching and experimenting) you can use boxing to use F # types as values:

> 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 = [];}

      

But I would stick with Option type, personally

+4


source







All Articles