2012-09-08 43 views
2

我可以避免向類中添加額外字段來存儲僅用於反序列化/序列化的數據嗎?哪裏最好存儲臨時反序列化數據?

假設我有一些類:

[Serializable] 
class MyClass { 
     [NonSerialized] 
     NonSerializableDataType myField; 

     SomeOtherDataType serializableTemporaryData; 

     [OnSerializing] 
     OnSerializing (StreamingContext context) { 
      // build serializableTemporaryData from myField 
     } 

     [OnDeserialized] 
     void OnDeserialized (StreamingContext context) { 
     // build myField from serializableTemporaryData 
     } 
} 

有什麼辦法,以避免在MyClass每個對象serializableTemporaryData場?例如,我可以把它變成靜態的(可能通過改變我的On ...方法)?

約束:我無法更改NonSerializableDataType的實現。

示例:假設myField包含資源的句柄。然後,在序列化時,我必須存儲一些關於如何在反序列化後獲取資源的信息,但我無法存儲句柄本身。如果我將句柄包裝到另一個類中,那麼我只是將問題轉移到了包裝類 - 然後我會問包裝類的問題。

+1

製作靜態在這裏是一個壞主意。考慮兩個線程作用於同一類的兩個對象,並進行序列化。 – Ankush

+0

你正在使用哪個序列化程序? Xml還是二進制?另外,你不能改變'NonSerializableDataType',但你可以繼承它嗎? –

+0

爲什麼你需要存儲並且每次都不能生成它? – MichaelT

回答

5

如果您需要控制序列化過程,您應該實現ISerialization接口。

[Serializable] 
public class MyClass: ISerializable 
{ 
    // As you are in control of serialization process now 
    // [Serialized] and [NonSerialized] attributes are no longer required 
    private NonSerializableDataType myField; 

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     // Create and populate your SomeOtherDataType local variable here, then push it into info variable 
     // Or even better, dont create SomeOtherDataType, just put additional serialization data into info variable, for example: 
     info.AddValue("URL", "http://this.way.com"); 
    } 

    protected MyClass(SerializationInfo info, StreamingContext context) 
    { 
     // Dont forget to define constructor for deserialization purpose 

     this.myField = new NonSerializableDataType(loadFromURL: (string)info.GetValue("URL", typeof(string))); 
    } 
} 

沒有額外的類僅用於序列化數據,沒有字段污染。唯一的潛在問題是觀察從這個類派生的任何可序列化的數據(如果需要,請覆蓋GetObjectData(...))。

更多信息:MSDN ISerializable

+0

謝謝。這似乎是我需要的。 – JohnB

3

還有就是serialization surrogates一個概念,它可以幫助你克服困難SomeNonSerializableType,因爲它正是爲此設計的原因。不過,這需要你有配置的可能性序列化代理,格式化程序創建時。否則,您需要通過執行ISerializable來自定義序列化過程。

+0

感謝您提供代理鏈接和提示。我會通過這個工作。 – JohnB