二进制序列化,我想我就快搞定了

本文关键字:序列化 二进制 | 更新日期: 2023-09-27 18:12:51

我一直在遵循二进制序列化指南(这个在这里:http://www.codeproject.com/Articles/1789/Object-Serialization-using-C),我想我终于几乎让它工作了。当我保存创建的文件时,但是当我尝试加载时,什么都没有加载。我觉得我就快成功了。任何建议都将不胜感激。下面是代码:

保存/加载类
[Serializable()]
public class SaveLoad : ISerializable
{
    public int GameDay = Date.GameDay;
    public List<Adventurer> Adventurers = FormMain.AdventurerManager.AdventurerList;
    public SaveLoad()
    {
        GameDay = 0;
        Adventurers = null;
    }
    public SaveLoad(SerializationInfo info, StreamingContext ctxt)
    {
        GameDay = (int)info.GetValue("Date", typeof(int));
        Adventurers = (List<Adventurer>)info.GetValue("Adventurers", typeof(List<Adventurer>));
    }
    public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
    {
        info.AddValue("Date", GameDay);
        info.AddValue("Adventurers", Adventurers);
    }
}

保存/加载方法:

    void btnSaveGame_Click(object sender, EventArgs e)
    {
        SaveLoad save = new SaveLoad();
        Stream stream = File.Open("SaveGame.osl", FileMode.Create);
        BinaryFormatter bformatter = new BinaryFormatter();
        bformatter.Serialize(stream, save);
        stream.Close();
    }
    void btnLoadGame_Click(object sender, EventArgs e)
    {
        SaveLoad load = new SaveLoad();
        Stream stream = File.Open("SaveGame.osl", FileMode.Open);
        BinaryFormatter bformatter = new BinaryFormatter();
        load = (SaveLoad)bformatter.Deserialize(stream);
        stream.Close();
        Date.CalculateDate();
        this.Visible = false;
        ((FormMain)(this.ParentForm)).ControlMainScreen.Visible = true;
    }

二进制序列化,我想我就快搞定了

我想你可能只是初始化时间有问题。

尝试将GameDay和adventers的初始化移到构造函数中,或者在构造函数中去掉它们的空值。完成以下操作后,代码基本可以工作了:

public SaveLoad()
{
    //GameDay = null;
    //Adventurers = null;
}

注意,我还必须确保Adventurer类具有Serialization属性。

下面是序列化的代码,为我工作(我不得不创建我自己的冒险家类,我用字符串替换了日期,因为我无法弄清楚你在做什么,或者它来自哪里。)我还用一些虚拟数据填充了冒险者列表,并注释掉了任何与表单相关的东西,我也没有相关的信息。

[Serializable()]
public class SaveLoad : ISerializable
{
    public string GameDay = null;
    public List<Adventurer> Adventurers = null; 
        //FormMain.AdventurerManager.AdventurerList;
    public SaveLoad()
    {
        GameDay = "Date";
        Adventurers = new List<Adventurer>() { new Adventurer { Name = "a1", Type = "t1" }, new Adventurer { Name = "a1", Type = "t1" } }; ;
    }
    public SaveLoad(SerializationInfo info, StreamingContext ctxt)
    {
        GameDay = (string)info.GetValue("Date", typeof(string));
        Adventurers = (List<Adventurer>)info.GetValue("Adventurers", typeof(List<Adventurer>));
    }
    public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
    {
        info.AddValue("Date", GameDay);
        info.AddValue("Adventurers", Adventurers);
    }
}
[Serializable()]
public class Adventurer
{
    public string Name { get; set; }
    public string Type { get; set; }
}
private void btnLoadGame_Click(object sender, EventArgs e)
    {
        SaveLoad sl = new SaveLoad();
        Stream stream = File.Open("SaveGame.osl", FileMode.Open);
        BinaryFormatter bformatter = new BinaryFormatter();
        sl = (SaveLoad)bformatter.Deserialize(stream);
        stream.Close();
        MessageBox.Show(sl.Adventurers.Count.ToString());
        //Date.CalculateDate();
        //this.Visible = false;
        //((Form1)(this.ParentForm)).ControlMainScreen.Visible = true;
    }
    private void btnSaveGame_Click(object sender, EventArgs e)
    {
        SaveLoad sl = new SaveLoad();
        Stream stream = File.Open("SaveGame.osl", FileMode.Create);
        BinaryFormatter bformatter = new BinaryFormatter();
        bformatter.Serialize(stream, sl);
        stream.Close();
    }

EDIT

@JasonHaley是对的,你有一个时间/初始化问题。

在你的Load按钮点击事件中你定义了一个新的名为Load的SaveLoad

创建一个对formmain . adventermanager . adventerlist

的引用

但是在反序列化过程中,这个引用被序列化到磁盘的对象(另一个冒险者列表)销毁,现在是一个不同于formmain . adventermanager . adventerlist

中定义的冒险者列表。

你需要加载到列表中…

void btnLoadGame_Click(object sender, EventArgs e)
{
    Stream stream = File.Open("SaveGame.osl", FileMode.Open);
    BinaryFormatter bformatter = new BinaryFormatter();
    SaveLoad load = (SaveLoad)bformatter.Deserialize(stream);
    // ***********************************
    FormMain.AdventurerManager.AdventurerList = SaveLoad.Adventurers
    // ***********************************
    stream.Close();
    Date.CalculateDate();
    this.Visible = false;
    ((FormMain)(this.ParentForm)).ControlMainScreen.Visible = true;
}