Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何反序列化并将数据转换为表单?_C#_Serialization_Deserialization_Generic List_Binaryformatter - Fatal编程技术网

C# 如何反序列化并将数据转换为表单?

C# 如何反序列化并将数据转换为表单?,c#,serialization,deserialization,generic-list,binaryformatter,C#,Serialization,Deserialization,Generic List,Binaryformatter,目标 我目前有保存信息的有效方法 然后,我希望程序在退出后单击“加载”按钮加载保存的状态 然后我希望程序在适当的位置显示数据 在表单中,我有两个DataGridView,一个用于员工,另一个用于主管 ============================================================= 方法 我已将两个通用列表序列化为一个.dat文件 BinaryFormatter bFormatter = new BinaryFormatter(); using (

目标

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

然后,我希望程序在退出后单击“加载”按钮加载保存的状态

然后我希望程序在适当的位置显示数据

在表单中,我有两个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);

然后该对象返回我需要的数据,但我无法将
对象obj
数据转换为可用格式,它被困在
对象obj
中。如果可能,我想尝试将其放回
员工列表中

与大多数其他序列化程序不同,它记录被序列化对象的完整.Net类型元数据。正如您所注意到的,它也存在于二进制文件中

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

var supervisors = (List<Supervisor>)bFormatter.Deserialize(fs);
var employees = (List<Employee>)bFormatter.Deserialize(fs);
如果是这样,您必须在对
serialize()
的一次调用中序列化员工和主管列表,因为
BinaryFormatter
仅在对
serialize()
反序列化()
的每次调用中保留对象图关系。单独通话时,相互关系将丢失。为避免此潜在问题,您可以将列表打包到单个根对象中,例如
列表

var bFormatter=new BinaryFormatter();
var root=新列表{主管,员工};
序列化(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();
var bFormatter=new BinaryFormatter();
var root=(List)bFormatter.Deserialize(fs);
var employees=root.OfType();
var supervisors=root.OfType().SelectMany(e=>e.ToList();

顺便说一句,使用
BinaryFormatter
进行序列化可能不是长期保存数据的最佳选择。如果在类中进行任何更改,则需要实现。另见。而且,
BinaryFormatter
完全基于文件中的类型信息构造对象这一事实会给反序列化不可信数据带来安全风险

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

命名空间WpfApplication3
{
公共部分类应用程序:应用程序
{
字符串路径=@“C:\Users\xxx\Desktop\myFile.dat”;
公共应用程序()
{
初始化组件();
//试验
列表列表=新列表();
列表添加(新员工(“aaa”);
列表添加(新员工(“bbb”);
List sList=新列表();
增加(新主管(“ccc”);
新增(新监管人(“ddd”);
SavedInfo SavedInfo=新的SavedInfo();
savedInfo.employeeList=eList;
savedInfo.supervisorList=sList;
SaveToFile(savedInfo);//保存到文件
SavedInfo newSaveGame=LoadFromFile();//从文件加载
foreach(newSaveGame.employeeList中的变量e)
Console.WriteLine(“员工:+e.name”);
foreach(newSaveGame.supervorlist中的变量e)
Console.WriteLine(“主管:+e.name”);
}
public void SaveToFile(SavedInfo objectToSerialize)
{
Stream=File.Open(路径,FileMode.Create);
BinaryFormatter bFormatter=新的BinaryFormatter();
序列化(流、对象序列化);
stream.Close();
}
public SavedInfo LoadFromFile()
{
如果(!System.IO.File.Exists(path))
返回新的SavedInfo();
SavedInfo对象序列化;
Stream=File.Open(路径,FileMode.Open);
BinaryFormatter bFormatter=新的BinaryFormatter();
objectToSerialize=(SavedInfo)bFormatter.Deserialize(流);
stream.Close();
返回对象序列化;
}
}
[可序列化()]
公共类SavedInfo
{
public List employeeList=新列表();
public List supervisorList=新列表();
}
[可序列化()]
公营雇员
{
公共字符串名称=”;
公共雇员(字符串名称)
{
name=eName;
}
}
[可序列化()]
公营班主任
{
公共字符串名称=”;
公共主管(字符串名称)
{
name=eName;
}
}
}

编辑:根据jdweng的评论进行编辑。我认为jdweng是对的。

首先,这是一种糟糕的数据存储方式,因为每次都必须保存两个列表。第二我敢打赌,只要稍加努力,主管就可以从员工那里继承,这样您只需要保存一个列表。反序列化列表后,如果使用DGV。您可以将它们设置为数据源,数据将自动显示。您是否在询问如何从列表中填充DataGridView?或者如何反序列化到您需要的列表中?@puropoix Supervisor确实继承自员工,我如何将其设置为数据源?但在此之前,我如何正确地反序列化?@Ciara-如何反序列化到列表为什么不创建包含这两个列表的类。然后序列化该类。
[Serializable]
public class Employee : Person
{
    public Supervisor Supervisor { get; set; }
}
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();
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;
        }
    }
}