17.2 为序列化配置对象
为了让一个对象支持.NET序列化服务,用户需要做的只是为每一个关联的类加上[Serializable]特性,真的就是这样简单。如果你觉得给定的类有一些成员数据不能(或可能不)参与到序列化配置中,可以在这些域前加上[NonSerialized]特性。如果在可被序列化的类中有成员变量不需要保存(比如,固定的值、随机值、瞬态数据等)并且希望减小持久化图的大小,这样做是很有用的。
让我们继续。下面这个Radio类被标记为[Serializable],除了一个成员变量(radioID)例外,它被标记为[NonSerialized],因此radioID类将不会被持久化到指定的数据流中。
[Serializable]
public class Radio
{
public bool hasTweeters;
public bool hasSubWoofers;
public double[] stationPresets;
[NonSerialized]
public string radioID = "XF-552RR6";
}
JamesBondCar类和Car基类也标记为[Serializable],并且定义了下列字段数据:
[Serializable]
public class Car
{
public Radio theRadio = new Radio();
public bool isHatchBack;
}
[Serializable]
public class JamesBondCar : Car
{
public bool canFly;
public bool canSubmerge;
}
注意,[Serializable]特性不能被继承,因此,如果从被标记为[Serializable]的类派生一个类,子类也必须被标记为[Serializable],否则它不能被持久化。实际上,对象图中的所有对象标上[Serializable]特性。如果试图使用BinaryFormatter或者SoapFormatter序列化一个非序列化的对象,在运行时将会收到一个SerializationException(序列化异常)的提示。
公共字段、私有字段和公共属性
注意,为了简化范例,上面用到每一个类中的字段数据都被定义为公共的。当然从面向对象的观点看,用公共属性公开私有字段数据更受欢迎。同样为了简化的需要,上面的类型也没有定义构造函数,因此所有未被赋值的字段数据将接收期望的默认值。
除了面向对象的设计原则之外,读者可能想知道不同的格式化方法指望类型的字段数据要如何定义,才能被序列化为流。答案是,这取决于具体情况。如果使用BinaryFormatter持久化一个对象,完全没有区别,这个类型被编程为序列化一个类型的所有可序列化的字段,不管它是公共字段、私有字段还是通过类型属性公开的私有字段。如果使用XmlSerializer或SoapFormatter类型,情况就大不同。这些类型只有字段数据的公共块或拥有公共属性的私有数据可以被序列化。
回想一下,如果有一些不想被持久化到对象图中的数据点,可以有选择地把公共或私有字段标记为[NonSerialized],像对Radio类型中的字符串域所做的那样。






