怎么了属性?

据我所知,当我反序列化缺少这个新成员的旧版本的类时,我必须使用[OptionalField]属性在我的类的较新版本中装饰一个新成员。

但是,在序列化类之后添加InnerTranslator属性时,下面的代码不会引发exception。 我在onDeserialization方法中检查属性是否为null(它确认它没有被序列化),但我原本希望代码抛出exception。 [OptionalField]属性本身是可选的吗?

class Program { static void Main(string[] args) { var listcol = new SortedList { {"Estados Unidos", "United States"}, {"Canadá", "Canada"}, {"España", "Spain"} }; var translator = new CountryTranslator(listcol); using (var file_stream=new FileStream("translator.bin",FileMode.Open)) { var formatter = new BinaryFormatter(); translator = formatter.Deserialize(file_stream) as CountryTranslator; file_stream.Close(); } Console.ReadLine(); } } [Serializable] internal class CountryTranslator:IDeserializationCallback { public int Count { get; set; } public CountryTranslator(SortedList sorted_list) { this.country_list = sorted_list; inner_translator = new List {"one", "two"}; } //[OptionalField] private List inner_translator; public List InnerTranslator { get { return inner_translator; } set { inner_translator = value; } } private SortedList country_list; public void OnDeserialization(object sender) { Debug.Assert(inner_translator == null); Count=country_list.Count; } } 

如果你换东西的话, BinaryFormatter 最好是非常脆弱的。 尤其是, 自动实现的属性,混淆 ,重命名,强命名等存在巨大问题。

我记得,有关[OptionalField]一些规则在发布之前发生了变化; 我期望,版本容忍的东西并没有像计划的那样容易实现。

我的建议:如果你想要版本容忍序列化(即你今天可以序列化它并用你的应用程序的下一个版本反序列化),那么不要使用BinaryFormatter ; 这是(IMO)仅适用于在相同版本(远程处理, AppDomain等)之间传递数据。

对于版本之间的工作,我建议基于合同的序列化; 像XmlSerializerDataContractSerializer (.NET 3.0),或二进制 – protobuf-net或类似工具。 所有这些在版本容差方面好得多(实际上,您甚至不需要将其反序列化为相同的Type ); 加上它们可以在平台之间使用 – 所以你可以在.NET中序列化并在java / C ++ /等中反序列化。