簡體   English   中英

為什么不能在類級別使用'NonSerialized'屬性?如何防止類的序列化?

[英]Why can't the 'NonSerialized' attribute be used at the class level? How to prevent serialization of a class?

我有一個使用二進制序列化進行深度克隆的數據對象。 此數據對象支持屬性更改事件,例如PriceChanged。

假設我將處理程序附加到PriceChanged。 當代碼嘗試序列化PriceChanged時,它會拋出一個異常,即處理程序未標記為可序列化。

我的選擇:

  • 在序列化之前,我無法輕松地從事件中刪除所有處理程序
  • 我不想將處理程序標記為可序列化,因為我還必須遞歸地標記所有處理程序依賴項。
  • 我不想將PriceChanged標記為NonSerialized - 有這樣的數十個事件可能有處理程序。 編輯:我不能這樣做的另一個原因是因為生成了數據類(以及事件),並且我無法直接控制生成代碼。 理想情況下,生成代碼只會將所有事件標記為NonSerialized。
  • 理想情況下,我希望.NET能夠在此時停止對象圖並使其成為“葉子”。 那么為什么.NET不允許將整個類標記為NonSerialized?

-

我終於通過使處理程序實現ISerializable並在serialize構造函數/ GetDataObject方法中不執行任何操作來解決此問題。 但是,處理程序仍然是序列化的,只是將其所有依賴項設置為null - 所以我也必須考慮到這一點。

有沒有更好的方法來阻止整個類的序列化? 也就是說,不需要考慮空依賴關系?

雖然我傾向於不同意這種方法(我只是將事件標記為NonSerialized,無論有多少)你可以使用序列化代理來做到這一點。

我們的想法是,您創建一個實現ISerializationSurrogate的對象,並基本上執行您正在執行的操作 - GetObjectData和SetObjectData方法中沒有任何內容。 不同之處在於您將自定義委托的序列化,而不是包含它的類。

就像是:

class DelegateSerializationSurrogate : ISerializationSurrogate {
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        // do nothing
    }
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        // do nothing
        return null;
    }
}

然后使用本MSDN專欄中列出的步驟將其注冊到格式化程序。 然后,只要格式化程序遇到委托,它就會使用代理而不是直接對委托進行序列化。

......有幾十個事件......

就個人而言,我只是添加非序列化標記,通過以下方式最容易完成類似字段事件:

[field: NonSerialized]
public event SomeEventType SomeEventName;

(您不需要添加手動支持委托)

您的序列化要求到底是什么? BinaryFormatter在許多方面是最不友好的序列化器; 對事件的影響有點難看,如果存儲它會非常脆弱(IMO它只適合運輸而不是存儲)。

然而; 有很多很好的選擇可以支持最常見的“深度克隆”場景:

  • XmlSerializer (但僅限於公共成員)
  • DataContractSerializer / NetDataContractSerializer
  • protobuf-net(包括用於此目的的Serializer.DeepClone

(請注意,在大多數序列化支持中,需要額外的屬性,因此首先添加[NonSerialized]屬性並沒有多大區別!)

暫無
暫無

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

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