如何反序列化然后将数据放入表格?

How to deserialize and then put data into form?

目标

我目前有一个保存信息的有效方法

然后我希望程序在退出后单击 'load' 按钮时加载保存的状态。

然后我希望程序在适当的地方显示数据

在表单中,我有两个 DataGridView,一个用于员工,另一个用于主管。

============================================= ================

方法

我已经将两个通用列表序列化为一个 .dat 文件

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

到目前为止,在 .dat 文件中,我有 3 名员工和 2 名主管,我不确定如何提取信息并将它们放入适当的位置

名单如下:

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

Employee e1 = new Employee(MemberJob.Employee, "Name", MemberSkills.CPlus | MemberSkills.CSharp, false);
Supervisor s1 = new Supervisor(MemberJob.Supervisor, "Another name", false); 
employees.Add(e1);
supervisors.Add(s1);

============================================= ============================

尝试

我广泛浏览了互联网和 Whosebug,但主要是它与我的上下文无关,或者他们正在使用我不想使用的 XML 格式。

我认为这只是复制 serialize 方法并将 bFormatter.Serialize(fs, employees); 更改为 bFormatter.Deserialize(fs, employees); 的情况,但我对反序列化列表后要做什么感到困惑.

 BinaryFormatter bFormatter = new BinaryFormatter();
 FileStream fs = File.Open(FILENAME, FileMode.Open);
 object obj = bFormatter.Deserialize(fs);

对象然后带回我需要的数据,但我无法将 object obj 数据放入可用格式,如果可能的话,它卡在 object obj 中我想尝试放入它回到 Employee list

与大多数其他序列化程序不同,BinaryFormatter records the full .Net type metadata of the objects being serialized. It also, as you have noted, allows multiple objects to be written sequentially 在二进制文件中。

因此,假设您知道二进制文件中应出现的对象序列,您可以在流上多次调用 Deserialize(fs),然后将返回的对象转换为您期望的对象:

var supervisors = (List<Supervisor>)bFormatter.Deserialize(fs);
var employees = (List<Employee>)bFormatter.Deserialize(fs);

也就是说,您的 SupervisorEmployee 类 中的任何一个都直接引用了彼此吗?比如像这样的?

[Serializable]
public class Employee : Person
{
    public Supervisor Supervisor { get; set; }
}

如果是这样,您必须在对 Serialize() 的一次调用中序列化员工和主管列表,因为 BinaryFormatter 仅保留每个列表中的对象图关系单次调用 Serialize()Deserialize()。使用单独的调用,相互关系将丢失。为了避免这个潜在的问题,您可以将您的列表打包到一个根对象中,例如 List<object>:

var bFormatter = new BinaryFormatter();
var root = new List<object> { supervisors, employees };
bFormatter.Serialize(fs, root);

然后,反序列化:

var bFormatter = new BinaryFormatter();
var root = (List<object>)bFormatter.Deserialize(fs);
var employees = root.OfType<IEnumerable<Employee>>().SelectMany(e => e).ToList();
var supervisors = root.OfType<IEnumerable<Supervisor>>().SelectMany(e => e).ToList();

顺便说一句,使用 BinaryFormatter 序列化可能不是长期保存数据的最佳选择。如果您对 类 进行任何更改,则需要实施 Version Tolerant Serialization. See also Can strong naming cause problems with object serialization in C#?BinaryFormatter 完全根据文件内的类型信息构造对象这一事实可能会引入反序列化不受信任数据的安全风险。

我送给你的圣诞礼物。希望能帮助到你。 :)

namespace WpfApplication3
{
    public partial class App : Application
    {
        string path = @"C:\Users\xxx\Desktop\myFile.dat";

        public App()
        {
            InitializeComponent();

            //Test
            List<Employee> eList = new List<Employee>();
            eList.Add(new Employee("aaa"));
            eList.Add(new Employee("bbb"));

            List<Supervisor> sList = new List<Supervisor>();
            sList.Add(new Supervisor("ccc"));
            sList.Add(new Supervisor("ddd"));

            SavedInfo savedInfo = new SavedInfo();
            savedInfo.employeeList = eList;
            savedInfo.supervisorList = sList;


            SaveToFile(savedInfo); //Save to file

            SavedInfo newSaveGame = LoadFromFile(); //Load from file

            foreach (var e in newSaveGame.employeeList)
                Console.WriteLine("Employee: " + e.name);

            foreach (var e in newSaveGame.supervisorList)
                Console.WriteLine("Supervisor: " + e.name);
        }

        public void SaveToFile(SavedInfo objectToSerialize)
        {
            Stream stream = File.Open(path, FileMode.Create);
            BinaryFormatter bFormatter = new BinaryFormatter();
            bFormatter.Serialize(stream, objectToSerialize);
            stream.Close();
        }

        public SavedInfo LoadFromFile()
        {
            if (!System.IO.File.Exists(path))
                return new SavedInfo();

            SavedInfo objectToSerialize;
            Stream stream = File.Open(path, FileMode.Open);
            BinaryFormatter bFormatter = new BinaryFormatter();
            objectToSerialize = (SavedInfo)bFormatter.Deserialize(stream);
            stream.Close();
            return objectToSerialize;
        }
    }

    [Serializable()]
    public class SavedInfo
    {
        public List<Employee> employeeList = new List<Employee>();
        public List<Supervisor> supervisorList = new List<Supervisor>();
    }

    [Serializable()]
    public class Employee
    {
        public string name = "";

        public Employee(string eName)
        {
            name = eName;
        }
    }

    [Serializable()]
    public class Supervisor
    {
        public string name = "";

        public Supervisor(string eName)
        {
            name = eName;
        }
    }
}

编辑:根据 jdweng 的评论进行编辑。我觉得jdweng说的对。