2012-07-24 37 views
0

我是序列化的新手,所以很可能我錯過了一些明顯的東西!如何序列化派生數據集的集合

我有一個名爲ResultsCollection的類,它是一個四維數據結構 - 從DataSet類派生的對象的集合。每個修改的DataSet都包含從DataTable派生的對象的集合。的代碼中的相關位是:

[Serializable] 
public class ResultsCollection : CollectionBase, ISerializable 
{ 
    // indexer 
    public MyDataSet this[int index] { get { return (MyDataSet)List[index]; } } 
} 
[Serializable] 
public class MyDataSet : DataSet, ISerializable 
{ 
    // member variable that *overrides* the Tables property of the standard DataSet class 
    public new TablesCollection Tables; 
} 
[Serializable] 
public class TablesCollection : CollectionBase, ISerializable 
{ 
    // indexer 
    public MyDataTable this[int index] { get { return (MyDataTable)List[index]; } } 
} 
[Serializable] 
public class MyDataTable : DataTable, ISerializable 
{ 
    ... 
} 

我已經通過包括公共序列化構造函數和公共GetObjectData使用功能實現ISerializable接口,如下所示:

// ResultsCollection -- serialize all variables and also the inner list itself 
public ResultsCollection(SerializationInfo info, StreamingContext ctxt) : base() 
{ 
    _memberVariable = (bool)info.GetValue("_memberVariable", typeof(bool)); 
    ArrayList innerList = (ArrayList)info.GetValue("List", typeof(ArrayList)); 
    InnerList.AddRange(innerList); 
} 
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) 
{ 
    info.AddValue("_memberVariable", _memberVariable); 
    info.AddValue("List", InnerList); 
} 

// MyDataSet -- call standard base-class (DataSet) serialization functions in addition to serializing members 
public MyDataSet(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt) 
{ 
    _memberVariable = (bool)info.GetValue("_memberVariable", typeof(bool)); 
    Tables = (TablesCollection)info.GetValue("Tables", typeof(TablesCollection)); 
} 
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) 
{ 
    base.GetObjectData(info, ctxt); 
    info.AddValue("_memberVariable", _memberVariable); 
    info.AddValue("Tables", Tables); 
} 

// TablesCollection -- serialize all variables and also the inner list itself 
public TablesCollection(SerializationInfo info, StreamingContext ctxt) : base() 
{ 
    _memberVariable = (bool)info.GetValue("_memberVariable", typeof(bool)); 
    ArrayList innerList = (ArrayList)info.GetValue("List", typeof(ArrayList)); 
    InnerList.AddRange(innerList); 
} 
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) 
{ 
    info.AddValue("_memberVariable", _memberVariable); 
    info.AddValue("List", InnerList); 
} 

// MyDataTable -- call standard base-class (DataTable) serialization functions in addition to serializing members 
public MyDataSet(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt) 
{ 
    _memberVariable = (bool)info.GetValue("_memberVariable", typeof(bool)); 
} 
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) 
{ 
    base.GetObjectData(info, ctxt); 
    info.AddValue("_memberVariable", _memberVariable); 
} 

我有一個單一的ResultsCollection對象我想存儲在ViewState中,以便在下次回傳時檢索它(因此所有這些麻煩)。對於最初的請求,事情似乎有效:我在序列化函數中設置了斷點,數據成員確實在序列化。但是,在反序列化時,成員變量被正確加載,但List對象充滿空成員。當我嘗試從ResultsCollection中的第一個MyDataSet對象中檢索DataSetName屬性時,我的代碼崩潰了。

+1

如果你是新的序列化,你可能要考慮http://code.google的.com/p/protobuf網/。我發現比[Serialization]屬性更容易使用。 – Liron 2012-07-24 20:02:35

+0

我覺得只使用''Serializable''要容易得多。您必須確保每個類與序列化類的關係都標有'[Serializable]'。 – 2012-07-24 20:26:25

+0

個人而言,我更喜歡XML序列化爲二進制。我發現使用起來更容易,並且能夠在事後查看原始數據,讓您知道是否有問題。話雖如此,我承認有時候會走錯路。我仍然更喜歡= D – Nevyn 2012-07-24 20:28:44

回答

0

原來,CollectionBase和ISerializable不兼容,可能是因爲CollectionBase的InnerList屬性是隻讀的。所以我需要做的是給從兩個CollectionBase中派生類中刪除的ISerializable的定義,即:

[Serializable] 
public class ResultsCollection : CollectionBase 
{ 
    // indexer 
    public MyDataSet this[int index] { get { return (MyDataSet)List[index]; } } 
} 
[Serializable] 
public class MyDataSet : DataSet, ISerializable 
{ 
    // member variable that *overrides* the Tables property of the standard DataSet class 
    public new TablesCollection Tables; 
} 
[Serializable] 
public class TablesCollection : CollectionBase 
{ 
    // indexer 
    public MyDataTable this[int index] { get { return (MyDataTable)List[index]; } } 
} 
[Serializable] 
public class MyDataTable : DataTable, ISerializable 
{ 
    ... 
}