【问题标题】:How to serialize a collection of derived data-sets如何序列化派生数据集的集合
【发布时间】:2012-07-24 19:58:18
【问题描述】:

我是序列化的新手,所以很可能我遗漏了一些明显的东西!

我有一个名为 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 属性时,我的代码崩溃了。

【问题讨论】:

  • 如果您不熟悉序列化,您可能需要查看code.google.com/p/protobuf-net。我发现它比 [Serialization] 属性更容易使用。
  • 我认为只使用[Serializable] 要容易得多。您必须确保每个与序列化类有关系的类也标记为[Serializable]
  • 就个人而言,我更喜欢 XML 序列化而不是二进制。我发现它更容易使用,并且能够在之后查看原始数据让您知道它是否有问题。话虽如此,我承认有时它是错误的。我还是更喜欢 =D
  • @LKIM -- 感谢您的建议。如果我在“常规代码”中找不到解决方案,我会试一试!
  • @Desolator -- 我试过了,但也没有用。我忘记了错误是什么,但我可以知道这是否有用。

标签: c# serialization collections dataset


【解决方案1】:

原来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
{
  ...
}

【讨论】:

    猜你喜欢
    • 2013-03-03
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 2011-03-17
    • 1970-01-01
    相关资源
    最近更新 更多