【摘要】Advanced Serialization: Format Your Way to Success with the .NET Framework Versions 1.1 and 2.0
序列号是门艺术,可用来将一个对象的状态持久化到内存或者文件里。(比如说我们要做Customer View,设计到持久化的时候,当然我们也可以直接读数据写XML,但这样通常会比较麻烦)
默认情况下,.Net的对象是不能序列化的,我们要想序列化它必须在其类上加[Serializable]的特性。如果我们不想序列化某个字段,我们可以给其加[NonSerialized]的标签。当然你可以让你的类继承自ISerializable,标明它是可序列化的。
.Net Framework通过反射的方式来实现序列化,读取对象的状态,然后写入stream里。
Delegates and Serialization
当序列化Delegate字段时,委托里的调用链(invocation list)都要被序列化, 这里就会遇到问题,我们必须保证Delegate里的所有目标对象必须都可被序列化,要不然序列此对象就会抛错。
例如如下代码,Subscriber类必须也是可序列化的。(当然如果其两个方法都定义为static的,Subscriber类不必是可序列化的,因为在Delegate里目标不会引用到Subscriber对象)。
Serilization with Event field
然而我们很难确定谁订阅了我们的事件,而且原则上讲是不必关心的,因此我们很难保证Subscriber这些对象都是可序列化的,因此我们一般将Event成员标为不可序列化,使用[NonSerialized]标签
对于那些标志了NonSerialized标签的字段,在反序列化的时候会为其赋默认值,您可以通过实现IDeserializationCallBack接口来定义你想要的默认值。public interface IDeserializationCallback
{
void OnDeserialization(object sender);
}
OnDeserialization方法会在反序列化完成后被调到。
如何您用的是Binary Formatter,您还可以使用到4个标签,来控制您在序列化或反序列化前后所想要调用的方法。[OnSerializing] [OnSerializing] [OnDeserializing] [OnDeserialized]。
调用的UML活动图如下:
注意的是这几个特性所能作用上的方法是用限制的,不能是静态的,虚方法或者泛型的。
另一点要注意的是总是先调用父类标有[OnSerializing]的方法,才调用子类相应的方法。
Generic Formatters
2.0里我们可以自定义一个IGenericFormatter接口简单对通过当前已有的Formatter进行包装来提供泛型的类型安全的Formatter接口。
Serialization and Versioning
对于Assembly版本引起的对象成员的改变,原文提到了可以使用[OptionalField]特性来处理,因为这种情况遇到较少,所有此处不做记录,可参考原文:)
Serialization and Cloning
当然用序列化的方式可以很方便地实现深Clone,前提是此对象可序列化:)
Manual Base Class Serialization
这个情况发生于子类想实现可序列化,但其父类没有实现ISerializable接口,而我们又不好改其代码。
方式就是子类实现ISerializable接口,然后通过反射方式得到父类所有字段信息并手动写入
貌似有3种方式可以实现,看得不是很明白这里就不做摘录了,用到时不妨再仔细研究研究
Securing Serialization
原文:http://msdn.microsoft.com/msdnmag/issues/04/10/AdvancedSerialization/