F#のレコードをJSONにシリアライズ

F#のスクリプト(fsx)で次の3つの方法を試してみました。

  • Json.NET
  • JavaScriptSerializer
  • DataContractJsonSerializer

#r "Newtonsoft.Json.dll"#r "System.Runtime.Serialization"

open Newtonsoft.Json
open System.IO
open System.Runtime.Serialization.Json
open System.Text

let handleWithJsonNet obj =
JsonConvert.SerializeObject(obj)

let handleWithJavaScriptSerializer obj =
let selializer = new JavaScriptSerializer()
selializer.Serialize(obj)

let haneldWithDataContractJsonSerializer obj =
let serializer = new DataContractJsonSerializer(obj.GetType());
use ms = new MemoryStream()
serializer.WriteObject(ms, obj)
Encoding.UTF8.GetString(ms.ToArray())

type Person = { Name : string; Age : int }
let p = { Name = "hoge"; Age = 20 }

printfn "Json.NET: %s" <| handleWithJsonNet p
printfn "JavaScriptSerializer: %s" <| handleWithJavaScriptSerializer p
printfn "DataContractJsonSerializer: %s" <| haneldWithDataContractJsonSerializer p

出力結果

Json.NET: {"Name":"hoge","Age":20}
JavaScriptSerializer: {"Name":"hoge","Age":20}
DataContractJsonSerializer: {"Age@":20,"Name@":"hoge"}

出力結果の最後の行を見てほしいんですが、DataContractJsonSerializerで変換するとキー名の最後に@がついてしまいます。これはF#のレコード内部のフィールド名ですね。なぜプロパティ名を使わないんだろう?と不思議に思ったんですが、たぶんF#のレコードにはsetterがないからかも。DataContractAttributeとDataMemberAttributeつけてキー名を明示すれば回避できるんですが、この挙動はちょっと面倒です。