F#记录类型的序列化 [英] F# Serialization of Record types

查看:96
本文介绍了F#记录类型的序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何使用可变对象在F#中进行序列化,但是有没有一种方法可以使用XmlSerializer或DataContractSerializer使用记录类型进行序列化/反序列化?看起来有一种方法可以使用KnownType属性对有区别的联合执行此操作,但是我正在寻找一种无需默认构造函数即可使用非可变记录的方法...

I know how to serialize in F# using mutable objects, but is there a way to serialize/deserialize using record types using either XmlSerializer or the DataContractSerializer? looks like there is a way to do this for a discriminated union using the KnownType attribute, but i am looking for a way to use non-mutable records without default constructor...

推荐答案

示例

The sample code for reading data from Freebase by Jomo Fisher uses DataContractJsonSerializer to load data into immutable F# records. The declaration of the record that he uses looks like this:

[<DataContract>]
type Result<'TResult> = { // '
    [<field: DataMember(Name="code") >]
    Code:string
    [<field: DataMember(Name="result") >]
    Result:'TResult // '
    [<field: DataMember(Name="message") >]
    Message:string }

此处的关键点是DataMember属性附加到实际用于存储数据的基础字段,而不附加到F#编译器生成的只读属性(使用属性).

The key point here is that the the DataMember attribute is attached to the underlying field that's actually used to store the data and not to the read-only property that the F# compiler generates (using the field: modifier on the attribute).

我不确定100%是否可以与其他类型的序列化一起使用(可能不会),但这可能是从...开始的有用指针.

I'm not 100% sure if this is going to work with other types of serialization (probably not), but it may be a useful pointer to start with...

编辑:我不确定这里是否缺少某些内容,但是以下基本示例对我来说很合适:

EDIT I'm not sure if I'm missing something here, but the following basic example works fine for me:

module Demo

#r "System.Runtime.Serialization.dll"

open System.IO  
open System.Text  
open System.Xml 
open System.Runtime.Serialization

type Test = 
  { Result : string[]
    Title : string }

do
  let sb = new StringBuilder()
  let value = { Result = [| "Hello"; "World" |]; Title = "Hacking" }
  let xmlSerializer = DataContractSerializer(typeof<Test>); 
  xmlSerializer.WriteObject(new XmlTextWriter(new StringWriter(sb)), value)
  let sr = sb.ToString()
  printfn "%A" sr

  let xmlSerializer = DataContractSerializer(typeof<Test>); 
  let reader = new XmlTextReader(new StringReader(sr))
  let obj = xmlSerializer.ReadObject(reader) :?> Test
  printfn "Reading: %A" obj

编辑2 如果要生成更清晰的XML,则可以添加如下属性:

EDIT 2 If you want to generate cleaner XML then you can add attributes like this:

[<XmlRoot("test")>] 
type Test = 
  { [<XmlArrayAttribute("results")>] 
    [<XmlArrayItem(typeof<string>, ElementName = "string")>] 
    Result : string[]
    [<XmlArrayAttribute("title")>] 
    Title : string }

这篇关于F#记录类型的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆