#r "../packages/Newtonsoft.Json.12.0.3/lib/netstandard2.0/Newtonsoft.Json.dll"
type [<Struct; System.ComponentModel.TypeConverterAttribute(typeof<CC>)>] C = A of string
and CC() =
inherit System.ComponentModel.TypeConverter()
override _.CanConvertFrom (_, t) = t = typeof<string>
override _.ConvertFrom(_, _, s) = s :?> string |> A |> box<C>
override _.CanConvertTo (_, t) = t = typeof<string>
override _.ConvertTo(_, _, s, _) = s :?> C |> fun (A s) -> s |> box<string>
Newtonsoft.Json.JsonConvert.SerializeObject {|a = A "123"|}
This results in val it : string = "{"a":{"Case":"A","Fields":["123"]}}", which indicates that the TypeConverter is not respected. This also happens for reference DUs.
However, this does not happen with JsonConverters:
#r "../packages/Newtonsoft.Json.12.0.3/lib/netstandard2.0/Newtonsoft.Json.dll"
type [<Struct; Newtonsoft.Json.JsonConverter(typeof<CC>)>] C = A of string
and CC() =
inherit Newtonsoft.Json.JsonConverter()
override _.CanConvert t = t = typeof<string>
override _.ReadJson (r, _, _, _) = r.ReadAsString() |> A |> box<C>
override _.WriteJson (w, v, _) = v :?> C |> fun (A s) -> s |> w.WriteValue
Newtonsoft.Json.JsonConvert.SerializeObject {|a = A "123"|}
This results in val it : string = "{"a":"123"}".
Compare this with records:
#r "../packages/Newtonsoft.Json.12.0.3/lib/netstandard2.0/Newtonsoft.Json.dll"
type [<Struct; System.ComponentModel.TypeConverterAttribute(typeof<CC>)>] C = { A: string }
and CC() =
inherit System.ComponentModel.TypeConverter()
override _.CanConvertFrom (_, t) = t = typeof<string>
override _.ConvertFrom(_, _, s) = { A = s :?> string } |> box<C>
override _.CanConvertTo (_, t) = t = typeof<string>
override _.ConvertTo(_, _, s, _) = (s :?> C).A |> box<string>
Newtonsoft.Json.JsonConvert.SerializeObject {|a = { A = "123"}|}
This also results in val it : string = "{"a":"123"}", which indicates that the TypeConverter is respected.
This shows that something is preventing TypeConverters in discriminated unions from being recognized. What would be the reason? JsonConverters are not usable in dictionary keys, so I would expect TypeConverters to perform better. What would be a viable approach to correctly serialize the aforementioned discriminated union?