怎么了[OptionalField]属性?

Dab*_*rnl 8 .net c# serialization fault-tolerance

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

但是,在序列化类之后添加InnerTranslator属性时,下面的代码不会抛出任何异常.我在onDeserialization方法中检查属性是否为null(它确认它没有被序列化),但我希望代码因此而抛出异常.[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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 8

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

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

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

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