二进制序列化,我想我几乎有它工作

时间:2013-05-09 23:22:57

标签: c# winforms

我一直在关注二进制序列化指南(这里这个: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;
    }

2 个答案:

答案 0 :(得分:1)

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

尝试将GameDay和Adventurers的初始化移动到构造函数中,或者在构造函数中删除它们。一旦我做了以下,代码几乎可以工作:

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

注意我还必须确保Adventurer类具有Seri​​alization属性。

以下是序列化对我有用的代码(我必须创建自己的Adventurer类,然后用字符串替换日期,因为我无法弄清楚你在做什么或它来自哪里我还在冒险家名单中填写了一些虚拟数据,并注释了与我也没有相关信息的表单内容。

[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();

    }

答案 1 :(得分:0)

修改

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

在“加载”按钮单击事件期间,您定义了一个名为“加载”的新SaveLoad

这将创建对FormMain.AdventurerManager.AdventurerList

的引用

但是在反序列化期间,此引用被序列化为磁盘的对象(另一个冒险者列表)破坏,现在是FormMain.AdventurerManager.AdventurerList中定义的冒险者的不同列表

您需要专门加载到该列表中......

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;
}