Effective C# 原则25: 让你的类型支持序列化
2009-02-19 08:16:24 来源:WEB开发网.Net的序列化是把类中所有成员变量保存到输出流中。另外,.Net的序列化还支持任意的对象图(object graph):即使你的对象上有一个循环引用,serialize 和deserialize 方法都只会为你的实际对象读取和储存一次。当一些web对象反序列化了以后,.Net序列化框架也可以创建这些web对象的引用。你创建的任何与web相关的对象,在对象图序列化以后,你都可以正确的保存它们。最后一个要注意的地方是Serializable 特性同时支持二进制和SOAP序列化。这一原则里的所有技术都支持这两种序列化格式。但是要记住:只有当所有类型的对象图都支持序列化时才能成功。这就是为什么要让所有的类型都支持序列化显得很重要了。一但你放过了一个类,你就轻意的给对象图开了个后门,以至于所有使用这个类的人,想要序列化对象图时变得更加困难。不久以后,他们就会发现不得不自己写序列化代码了。
添加Serializable特性是一个最简单的技术来支持对象的序列化。但最简单的方案并不是总是正确的方案。有时候,你并不想序列化对象的所有成员:有些成员可能只存在于长期操作的缓存中,还有一些对象可能占用着一些运行时资源,而这些资源只能存在于内存中。你同样可以很好的使用特性来控制这些问题。添加NonSerialized特性到任何你不想让它序列化的数据成员上。这给它们标上了不用序列化的标记:
Serializable]
public class MyType
{
private string _label;
[NonSerialized]
private int _cachedValue;
private OtherClass _object;
}
你,做为类的设计者,非序列化成员给你多添加了一点点工作。在序列化过程中,序列化API不会为你初始化非序列化成员。因为类型的构造函数没有被调用,所以成员的初始化也不会被执行。当你使用序列化特性时,非序列成员就保存着系统默认值:0或者null。当默认的0对初始化来说是不正确的,那么你须要实现IDeserializationCallback 接口,来初始化这些非序列化成员。框架会在整个对象图反序列化以后,调用这个方法。这时,你就可以用它为所有的非序列化成员进行初始化了。因为整个对象图已经载入,所以你的类型上的所有方法的调用及成员的使用都是安全的。不幸的是,这不是傻瓜式的。在整个对象图载入后,框架会在对象图中每个实现了IDeserializationCallback接口的对象上调用OnDeserialization方法。对象图中的其它任何对象可以在OnDeserialization正在进行时调用对象的公共成员。如果它们抢在了前面,那么你的非序列化成员就是null或者0。顺序是无法保证的,所以你必须确保你的所有公共成员,都能处理非序列化成员还没有初始化的这种情况。
- ››Effective C# 原则40:根据需求选择集合
- ››Effective C# 原则41:选择DataSet而不是自定义的...
- ››Effective C# 原则42:使用特性进行简单的反射
- ››Effective C# 原则43:请勿滥用反射
- ››Effective C# 原则44:创建应用程序特定的异常类
- ››Effective C# 第6章:杂项
- ››Effective C# 原则45:选择强异常来保护程序
- ››Effective C# 原则47:选择安全的代码
- ››Effective C# 原则48:了解更多的工具和资源
- ››Effective C# 原则49:为C#2.0做好准备
- ››Effective C# 原则50:了解ECMA标准
- ››Effective C# 原则系列文章目录
更多精彩
赞助商链接