C# 什么';[OptionalField]属性怎么了?
据我所知,当我反序列化缺少新成员的类的旧版本时,我必须使用[OptionalField]属性在类的新版本中修饰新成员 但是,在序列化类后添加InnerTranslator属性时,下面的代码不会引发异常。我在onDeserialization方法中检查属性是否为null(这确认了它没有被序列化),但我希望代码会因此引发异常。 [OptionalField]属性本身是可选的吗C# 什么';[OptionalField]属性怎么了?,c#,.net,serialization,fault-tolerance,C#,.net,Serialization,Fault Tolerance,据我所知,当我反序列化缺少新成员的类的旧版本时,我必须使用[OptionalField]属性在类的新版本中修饰新成员 但是,在序列化类后添加InnerTranslator属性时,下面的代码不会引发异常。我在onDeserialization方法中检查属性是否为null(这确认了它没有被序列化),但我希望代码会因此引发异常。 [OptionalField]属性本身是可选的吗 class Program { static void Main(string[] args) {
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;
}
}
类程序
{
静态void Main(字符串[]参数)
{
var listcol=新分类列表
{
{“美国”},
{“加拿大”、“加拿大”},
{“西班牙”}
};
var translator=新的CountryTranslator(listcol);
使用(var file_stream=newfilestream(“translator.bin”,FileMode.Open))
{
var formatter=新的二进制格式化程序();
translator=格式化程序。反序列化(文件流)为CountryTranslator;
文件_stream.Close();
}
Console.ReadLine();
}
}
[可序列化]
内部类CountryTranslator:IDeserializationCallback
{
公共整数计数{get;set;}
公共国家翻译(分类列表分类列表)
{
this.country\u list=已排序的\u list;
内部翻译=新列表{“一”、“二”};
}
//[可选字段]
私有列表内部_转换器;
公共列表内部翻译器
{
获取{return internal_translator;}
设置{internal_translator=value;}
}
私人分类列表国家/地区列表;
公共序列化(对象发送方)
{
Assert(内部_转换器==null);
Count=国家/地区列表。Count;
}
}
二进制格式化程序
在最好的情况下,如果您更改内容,它会非常脆弱。不仅如此,还有很多问题需要解决,例如,命名、重命名、强命名等
我记得,关于[OptionalField]
的一些规则在发布之前发生了变化;我想,容忍版本的事情并不像计划的那样容易
我的建议:如果您想要版本容忍序列化(即,您可以今天对其进行序列化,并使用下一版本的应用程序对其进行反序列化),则不要使用BinaryFormatter
;这(IMO)仅适用于在相同版本(远程处理、AppDomain
s等)之间传递数据
对于版本之间的工作,我建议基于契约的序列化;类似于
XmlSerializer
和DataContractSerializer
(.NET3.0),或者针对二进制或类似工具。所有这些在版本容忍度方面都要好得多(实际上,您甚至不需要将其反序列化为相同的类型
);另外,它们可以在平台之间使用-因此您可以在.NET中序列化,并在java/C++/等中反序列化。我刚刚发现,当内部转换器没有使用[OptionalField]属性装饰时,SOAP格式化程序确实会引发异常。这与我所寻找的答案不完全相同,但是我发现自从你在这篇文章中建议使用DataContractSerializer之后,我已经转而专门使用DataContractSerializer。所以还是谢谢你;-)您是否会将[OptionalField]用于布尔或整数等值类型?或者该属性仅与OP问题中的引用类型相关?