2011-09-23 19 views
0

除了訪問哈希表和轉換值類型時的速度問題,這真的很糟糕嗎?使用Hashtable來存儲屬性來打擊序列化版本控制

[Serializable] 
public class Cheat : ISerializable 
{ 
    public Cheat() { } 

    public string Orange { get { return Convert.ToString(_mData["Orange"]); } set { _mData["Orange"] = value; } } 

    public List<int> Ints { get { return (List<int>)(_mData["Ints"]); } set { _mData["Ints"] = value; } } 

    #region ISerializable Members 

    protected Hashtable _mData = new Hashtable(); 

    protected Cheat(SerializationInfo info, StreamingContext context) 
    { 
     _mData = (Hashtable)info.GetValue("_mData", typeof(Hashtable)); 
    } 

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("_mData", _mData); 
    } 

    #endregion 
} 
+0

在什麼方面?在.NET 2.0+中,當發生反序列化時,數據模型屬性的未識別的更新版本將自動被忽略。使用BinaryFormatter時,此行爲不需要代碼。 –

+0

我不知道它還有什麼不好。這就是我問的原因。我已經閱讀了http://msdn.microsoft.com/en-us/library/ms229752(v=vs.80).aspx中有關.NET 2.0的改進和OptionValue選項,但是使用Hashtable似乎可以更容易地解決即時問題? – Jake

回答

0

通過使用ISerializable接口系列化你基本上是採取控制序列化進程。這使您可以完全控制處理序列化模型類的版本控制。所以如果你願意的話,你甚至可以反序列化到一個完全不同的類。鑑於上面的例子,序列化成一個Hashtable不會增加價值。

正如您指出的那樣,它會降低速度,因爲您必須爲每個屬性請求取消裝箱對象。如果你有很多財產讀數,那麼這可能真的加起來。

像這樣的散列表情景最適合用於必須將不可變類型(比如多個字符串)傳遞給調用方法的情況。在這種情況下,留下裝箱的屬性可能會帶來一些好處。但是,因爲您的_mData字段受到保護,而您正在專門公開List<int>string類型的屬性,所以我假設您不打算這樣做。 如果你想繼續你的模型,你應該至少緩存你的屬性作爲強類型字段和隱藏類型只有一次讀取。

與版本控制特別相關,如果您希望將來更新模型或者現在對兼容性有明確的需求,現在可以識別模型版本。以前,當我完成這個操作時,我已經使用了一個標記字段(或者XML序列化的XML屬性)和一個版本號。

我的建議是將序列化和反序列化爲您需要的類型。如果你使用後者版本,那麼允許在你受保護的構造函數和GetObjectData方法中兼容。

+0

「你應該至少緩存你的屬性作爲強類型字段和隱藏類型一次只讀一次。」 - 在發佈問題後我想到了這一點。使用版本標記字段的問題是我必須將條件子句放在構造函數中才能確定要去除什麼和不去哪些東西。如果有新的程序員進來,他必須知道每個正在使用的類的單個版本,然後才能避免錯誤。我會多考慮一下。謝謝。 – Jake

相關問題