簡體   English   中英

二進制序列化和自動屬性

[英]Binary serialization and automatic properties

我有一個這樣的課:

public class Foo
{
    public IBar {get;set;}
    //tons of other properties
}

public interface IBar
{
    //whatever
}

該類用於二進制序列化(標准使用BinaryFormatter)。 IBar的實現標有[Serializable],所以一切正常。

現在我不想序列化Bar並保留向后兼容性(無論如何都沒有在代碼中引用)。 NonSerialized屬性似乎就足夠了。 但是它只能應用於字段,而不能應用於自動屬性。 所以我嘗試了這個:

public class Foo
{
    private IBar _bar;
    [NonSerializable]
    public IBar Bar 
    {
        get { return _bar; }
        set { _bar = value; }
    }
}

令人驚訝的是它運作良好 - 我可以將舊的Foos和新的Foos反序列化。

我的問題是:如果這些是序列化的字段並且自動屬性的支持字段可能在其名稱中包含一些非C#字符,它怎么可能有效呢?

換一種說法:

Old Foo的IBar字段名稱(我猜):k__BackingField

New Foo的IBar字段名稱:_bar

顯然它們不匹配,所以BinaryFormatter如何克服這個問題?

我認為你的例子中有一些奇怪的東西。 BinaryFormatter不應該能夠處理這個問題(據我所知,除非我在4.5中對此進行了更改),這就是為什么如果需要向后兼容性則使用它是非常危險的。 您確定該值是從舊版本序列化並反序列化為新版本嗎? 你能驗證反序列化的數據是否匹配,並且不是空的?

對於驗證它工作程序的完整的例子,在這里看到。 http://www.infragistics.com/community/blogs/josh_smith/archive/2008/02/05/automatic-properties-and-the-binaryformatter.aspx

您將看不到任何異常,但名為xyz__backingfield的字段中的舊值將丟失,並在新類中被默認值替換。

如果您想要向后兼容,請避免使用自動屬性,否則您很快就會遇到麻煩。 實際上它並不重要,因為默認(自動)模式下的BinaryFormatter僅在您想要序列化對象並在同一應用程序中再次反序列化它們時才真正有用,例如復制和粘貼或類似操作。 在這種情況下,您沒有版本控制問題,因為序列化和反序列化都是相同的代碼。

要使序列化向后兼容而不會失去理智,請確保您完全控制架構。 你有很大機會避免麻煩的序列化器的好例子是DataContractSerializer,Json.NET或Protocol緩沖區(例如protobuf-net)。

作為最后一種可能性,您可以實現ISerializable並使用BinaryFormatter的字典存儲,但是無論如何您都有手動滾動序列化的所有缺點。

在旁注中,如果要將屬性應用於后備字段,請嘗試[field:AttriuteType],這對於將事件的后備字段標記為非序列化非常有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM