F#中的XML序列化 - 面向对象网 f# 学习 对象 - 面向对象技术开发

面向对象技术开发

会员投稿 投稿指南 站长资讯通告:
您的位置: 首页 > OOP语言 > F# > 正文

F#中的XML序列化

来源: www.bianceng.cn 阅读:

这两天在用F#写一小段代码,需要把一些对象存到外部文件中去。这个功能很容易,因为.NET本身就内置了序列化功能。方便起见,我打算将这个对象序列化成XML而不是二进制数据流。这意味着我需要使用XmlSerializer而不是BinaryFormatter。这本应没有问题,但是在使用时候还是发生了一些小插曲。

定义类型

在F#中有多种定义方式。除了F#特有的Record类型外,在F#中也可以定义普通的“类”,如:

#light

module XmlSerialization

type Post() =

    [<DefaultValue>]
    val mutable Title : string

    [<DefaultValue>]
    val mutable Content : string

    [<DefaultValue>]
    val mutable Tags : string array

上面的代码在XmlSerialization模块中定义了一个Post类,其中包含三个公开字段。简单地说,它和C#中的如下定义等价:

public class Post
{
    public string Title;

    public string Content;

    public string[] Tags;
}

可见,在定义这种简单类型时,F#并没有什么优势,反而需要更多的代码。

使用XmlSerializer进行序列化

原本我以为使用XmlSerializer来序列化一个对象非常容易,写一个简单的(泛型)函数就可以了:

let byXmlSerializer (graph: 'a) =
    let serializer = new XmlSerializer(typeof<'a>)
    let writer = new StringWriter()
    serializer.Serialize(writer, graph)
    writer.ToString()

使用起来更加不在话下:

let post = new XmlSerialization.Post()
post.Title <- "Hello"
post.Content <- "World"
post.Tags <- [| "Hello"; "World" |]

let xml = XmlSerialization.byXmlSerializer(post)

但是,在运行的时候,XmlSerializer的构造函数却抛出了InvalidOperationException:

XmlSerialization cannot be serialized. Static types cannot be used as parameters or return types.

这句话的提示似乎是在说XmlSerialization是一个静态类型——但这其实是F#的模块啊。不过使用.NET Reflector查看编译后的程序集便会发现,其实Post类是这样定义的:

public static class XmlSerialization
{
    public class Post { ... }
}

虽然.NET中也有“模块”的概念,但是它和F#中的模块从各方面来讲几乎没有相同之处。F#的模块会被编译为静态类,自然模块中的方法或各种函数便成为静态类中的内嵌类型及方法。这本没有问题,从理论上来说XmlSerializer也不该有问题,不是吗?

Tags:
相关文章列表: