据我了解,当我反序列化缺少此新成员的类的旧版本时,我必须使用 [OptionalField] 属性来装饰类的新版本中的新成员。
但是,当序列化类后添加 InnerTranslator 属性时,下面的代码不会引发异常。我在 onDeserialization 方法中检查该属性是否为空(这确认它没有被序列化),但我预计代码会因此抛出异常。
[OptionalField] 属性本身是可选的吗?
class Program
{
static void Main(string[] args)
{
var listcol = new SortedList<string,string>
{
{"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<string,string> sorted_list)
{
this.country_list = sorted_list;
inner_translator = new List<string> {"one", "two"};
}
//[OptionalField]
private List<string> inner_translator;
public List<string> InnerTranslator
{
get { return inner_translator; }
set { inner_translator = value; }
}
private SortedList<string, string> country_list;
public void OnDeserialization(object sender)
{
Debug.Assert(inner_translator == null);
Count=country_list.Count;
}
}
BinaryFormatter
是,在best很多时候,如果你改变一些事情,就会变得非常脆弱。更重要的是,存在巨大的问题自动实现的属性,混淆、重命名、强命名等。
我记得有一些规则[OptionalField]
在发布之前发生了变化;我预计,版本宽容的事情并没有像计划的那样容易实现。
我的建议:如果您想要版本容忍的序列化(即您今天可以序列化它并使用应用程序的下一个版本反序列化它),那么不要使用BinaryFormatter
;这(IMO)仅适用于在same版本(远程处理,AppDomain
s, etc).
对于版本之间的工作,我建议基于契约的序列化;像XmlSerializer
and DataContractSerializer
(.NET 3.0),或二进制 -protobuf网络或类似的工具。所有这些都是much更好的版本容错性(事实上,您甚至不需要将其反序列化为相同的版本)Type
);另外,它们可以在平台之间使用 - 因此您可以在 .NET 中序列化并在 java/C++/等中反序列化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)