“[OptionalField]”属性有什么作用?

9
根据我的理解,当我反序列化一个旧版本且没有新成员的类时,我需要在我的类的新版本中使用[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;
    }
}

我刚刚发现,当内部转换器未装饰[OptionalField]属性时,SOAP格式化程序会抛出异常。 - Dabblernl
1个回答

9

BinaryFormatter在改变内容时非常脆弱,至少在自动实现属性,混淆、重命名、强命名等方面存在巨大问题。

据我回忆,在发布前关于[OptionalField]的一些规则发生了变化;我预计版本兼容性并没有像计划的那样容易实现。

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

对于版本之间的工作,我建议使用基于契约的序列化;例如XmlSerializerDataContractSerializer(.NET 3.0),或者对于二进制- protobuf-net 或类似的工具。所有这些工具在版本兼容性方面都要好得多(事实上,您甚至不需要将其反序列化为相同的Type);此外它们可以在各个平台之间使用 - 因此你可以在.NET中序列化并在Java/C++/等中反序列化。

1
不完全是我寻找的答案,但我发现自从你在这篇文章中建议使用DataContractSerializer以来,我已经完全转向使用它了。所以还是谢谢你;-) - Dabblernl
1
你会在布尔值或整数等值类型中使用[OptionalField]吗?还是这个属性只适用于像OP问题中的引用类型? - Fabian Bigler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接