前几天写了一篇.NET序列化概述性的文章,有朋友说对技术的描述不够详细,因此准备写一系列文章,以一个实例为基础,详细描述各种序列化的使用方法和注意事项。这一系列文章是为不熟悉序列化的读者准备的,已用过序列化的可以只看一下每篇中加粗的一句话,感兴趣再阅读全文。文中的示例类Voucher和VoucherItem非常简化,实际中的凭证包含更多的信息。
财务系统中经常要与凭证打交道,在这篇文章里,我们要实现一个Voucher类,它包含凭证和业务信息,并且能够保存为磁盘文件,以便于没有专用网络的分布式企业中,可以在终端输入凭证,然后通过拨号的方式将凭证批量更新到中心业务系统中。
凭证中除了包含凭证号,制单人,制单时间等外,还包含多条项目。假设凭证项目也由其他人完成,以Assembly的方式提供,类名为VoucherItem,其定义如下:
public class VoucherItem


{

public VoucherItem()
{}

public string AccountId
{get;set;}

public decimal DebitAmount
{get;set;}

public decimal CreaditAmount
{get;set;}
}
首先,我们要实现Voucher的主体类及其序列化,然后再把VoucherItem加到Voucher类上。
public class Voucher


{
private string voucherId;
private string creator;
private DateTime createTime;
private string description;
public Voucher(string voucherId, string creator, DateTime createTime)

{
this.voucherId = voucherId;
this.creator = creator;
this.createTime = createTime;
}
public string VoucherId

{
get

{
return voucherId;
}
}
public string Creator

{
get

{
return creator;
}
}
public DateTime CreateTime

{
get

{
return createTime;
}
}
public string Description

{
get

{
return description;
}
set

{
description = value;
}
}
}
为了将Voucher保存到磁盘,考虑最直接的方法是序列化,而为了通过拨号传到业务中心的需要,应当保存较小的磁盘文件,所以使用二进制序列化。
序列化代码如下:
public class VoucherSerializer


{
public VoucherSerializer()

{
}
public void Serialize(string filename, Voucher voucher)

{
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream(filename, FileMode.Create);
formatter.Serialize(fs, voucher);
fs.Close();
}
}
从上面的代码可以看出,借助.NET Framework的帮助,实现类的二进制序列化是非常容易的。序列化方法写好后,马上用NUnit做一个测试类。
[TestFixture]
public class VoucherTest


{
public VoucherTest()

{
}
[Test]
public void TestSerializeVoucher()

{
Voucher voucher = new Voucher("2005012900001", "xingd", DateTime.Now);
VoucherSerializer serializer = new VoucherSerializer();
serializer.Serialize("voucher.dat", voucher);
}
}
兴冲冲地打开NUnit GUI,选中Assembly,运行测试。
啊,怎么会有错误呢,这么简单的类。
GeneralLedger.VoucherTest.TestSerializeVoucher : System.Runtime.Serialization.SerializationException : The type GeneralLedger.Voucher in Assembly Voucher, Version=1.0.1855.38026, Culture=neutral, PublicKeyToken=null is not marked as serializable.
原来是这个错。能够进行二进制序列化的类必须在类定义中添加SerializableAttribute。对Voucher类进行如下修改:
[Serializable]
public class Voucher
运行NUnit,测试通过,生成的文件内容如下:
后面的随笔将会对此文件的格式进行分析。