【问题标题】:How to serialise generic list?如何反序列化通用列表?
【发布时间】:2015-12-23 19:44:58
【问题描述】:

我有一个employeessupervisors 的通用列表

List<Employee> employees = new List<Employee>();
List<Supervisor> supervisors = new List<Supervisor>(); 

它们都是我标记为[Serializable]employee 类的一部分

我可以把这两个列表放到另一个列表中,以便更容易序列化吗?

我看过序列化教程,但它们只指定了一个或更少的通用列表。

我提供了一个模板,我想单击“保存”按钮并完成序列化过程,最好将两个列表合并为一个更大的列表。

private void btnSave_Click(object sender, EventArgs e)
{
     FileStream outFile;
     BinaryFormatter bFormatter = new BinaryFormatter();
}

【问题讨论】:

    标签: c# generics serialization filestream generic-list


    【解决方案1】:

    您实际上可以将两个列表序列化为一个流:

    using (FileStream fs = new FileStream(..., FileMode.OpenOrCreate)) {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(fs, employees);
        bf.Serialize(fs, supervisors);
    }
    

    BinaryFormatter 以元数据作为数据块的前缀,这显然也允许它将数据连接到一个文件。为了回读supervisors,您必须先加载另一个列表。由于列表不是固定长度的记录,因此当您重写第一个列表时,第二个列表可能会变得不可用,并且要么在孤立数据后面丢失它,要么覆盖它的一部分。

    由于有很多事情可以阻止它工作,因此很容易为多个人创建一个“持有人”或容器类:

    [Serializable()]
    public class BFHolder
    {
        public List<Employee> employees { get; set; }
        public List<Supervisor> supervisors { get; set; }   
        public BFHolder()
        {
        }
    }
    

    反序列化后,可以根据需要拉出列表。

    还有一个——更好的——选项是ProtoBuf-Net(向下滚动到自述)。除了比 BinaryFormatter 更快和创建更小的输出之外,它还包括将多个对象序列化为一个流的方法。

    using (FileStream fs = new FileStream(..., FileMode.OpenOrCreate)) {
        Serializer.SerializeWithLengthPrefix<List<Employee>>(fs, employees,
                        PrefixStyle.Base128);
        Serializer.SerializeWithLengthPrefix<List<Supervisor>>(fs, supervisors,
                        PrefixStyle.Base128);
    }
    

    【讨论】:

    • 我必须在usings 中说明什么才能操作您的ProtoBuf-Net 方法?
    • using 块只会在您完成后关闭并处理流;它所缺少的只是文件名。 ProtoBuf-Net 是不同的序列化程序而不是不同的方法(见链接);好处之一是,如果您正在进行数据传输,您可以从一个程序集序列化并在另一个程序集中反序列化。 BinaryFormatter 本机不允许这样做。
    【解决方案2】:

    您可以将此列表放在另一个类容器中并对其进行序列化/反序列化。

    [Serializable]
    public class Container 
    {
         public List<Employee> employees = new List<Employee>();
         public List<Supervisor> supervisors = new List<Supervisor>();
    } 
    

    【讨论】:

      猜你喜欢
      • 2013-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      相关资源
      最近更新 更多