Welcome

首页 / 软件开发 / C# / Effective C#原则25 让你的类型支持序列化

Effective C#原则25 让你的类型支持序列化2010-12-11 博客园 Wu.Country@侠缘译对象的持久是类型的一个核心功能。这是一个在你忽略对它的支持以前,没 有人会注意到的基本元素之一。 如果你的类型不能恰当的支持序列化,那么对 于把你类的做为基类或者成员的开发人员来说,你会给他们增加很多的工作量。 当你的类型不支持序列化时,他们不得不围绕这工作,自己添加实现这个标准的 功能。而对于不能访问类的私有成员的开发人来说,恰当的实现你的类型的序列 化是不太可能的。如果你的类型不支持序列化,那么对于你的用户来说,想再要 实现实它是很困难或者根本就不可能的事。

取而代之的是,为你的实际 类型添加序列化。对于那些不用承载UI元素,窗口,或者表单的类型来说这是有 实际意义的。感觉有额外的工作是没有理由的,.Net的序列化是很简单的,以至 于你没有任意的借口说不支持它。在多数情况下,添加Serializable特性就足够 了:

[Serializable]
public class MyType
{
private string _label;
private int _value;
}

只添加一个Serializable特性就足以让它可以序列化,是因为这 它的成员都是可序列化的:string和int都是.Net序列化支持的。无论是否可能 ,都要给类型添加序列化支持是很重要的,原因在你添加另一个类做为新类的成 员时就很明显了:

[Serializable]
public class MyType
{
private string _label;
private int _value;
private OtherClass _object;
}

这里的Serializable特性只有在OtherClass也支持序列化时才有 效。如果OtherClass不支持序列化,那么你在序列化MyType时,因为OtherClass 对象也在里面,你会得到一个运行时错误。这只是因为对OtherClass的内部结构 不清楚,而使序列化成为不可能。

.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;
}