问题描述
我知道如何使用可变对象在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#记录类型的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!