本文介绍了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...

推荐答案

示例从Freebase读取数据的代码使用DataContractJsonSerializer将数据加载到不可变的F#记录中.他使用的记录声明如下:

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#记录类型的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 18:18
查看更多