利用IXmlSerializable接口来对序列化的过程进行完全的控制
IXmlSerializable接口的定义如下,其中ReadXml是用来进行反序列化的,而WriteXml则是进行序列化的,GetSchema函数可以不实现。
// Summary:其使用方法很简单,这里不再赘述代码。在序列化的时候,只需在WriteXml方法中,将本对象的属性写入到writer之中;而反序列化的时候,就是在ReadXml方法中,将Xml中的数据读出,并且赋给各成员变量。
// Provides custom formatting for XML serialization and deserialization.
public interface IXmlSerializable
{
XmlSchema GetSchema();
void ReadXml(XmlReader reader);
void WriteXml(XmlWriter writer);
}
序列化的对象不要循环引用
假如我们我们在为User类型增加下面这样一个成员变量:
public User friend=null;并且将main函数中部分代码修改如下,会出现什么样的效果呢?
User user = new User();//创建一个用户对象显然序列user对象的时候会出现运行时错误,因为user字段中包含了user2,而user2的字段中又包含了user,这样序列化的时候就会形成循环,永无止境了。幸好我们的.Net Fraemwork相当的健壮,它并不会陷入到死循环中,但是会抛出一个异常,报告出这个错误。所以我们在使用序列化的时候,应该避免这种情况,我们可以采用如下方式:
user.name = "张三";
user.age = 20;
User user2 = new User();//创建一个用户对象
user2.name = "李四";
user2.age = 20;
user.friend = user2; //User2是User的朋友
user2.friend = user; //User也是User2的朋友
xs.Serialize(xw, user);//这里会报错
为“Friend”字段加上[XmlIgnore]来使friend字段在序列化的过程中被忽略。
如果我们确实需要friend的信息,我们可以为其增加一个新的属性叫做”FriendName”,并且将其包括在序列化中即可。
总结
曾几何时,实现将运行时的数据保存到文件中并再读出来的功能是多么痛苦的一件事情,而制定专用的通信协议并且将需要的数据转化网络流也是多么伤透脑筋的事情,如今,dotNet平台已经给我们提供了强大的序列化器,是的我们再完成这些工作的时候事半功倍,无论你现在是否目前需要序列化的功能,好好地掌握它将会让你受益无穷。