虽然我实现了GetObjectData方法和Constructor,但DeSerialization不起作用

时间:2009-08-03 13:59:39

标签: c# .net serialization

我在类中有一个静态通用字典。由于静态memeber无法序列化,所以我已经实现了ISerializable接口和方法GetObjectData来序列化。我有一个构造函数,它也将接受SerializationInfo和StreamingContext来对dictionay进行deserliaze。现在,当我尝试序列化和反序列化时,它总是返回1(thoug我添加了2个条目)。请找到pseduo代码 -

[Serializable]
public class MyClass : ISerializable
{
  internal  static Dictionary<long, string> dict = new Dictionary<long,string>();

  public void GetObjectData(SerializationInfo info, StreamingContext context)
  {
   info.AddValue("static.dic", MyClass1.dict, typeof(Dictionary<long, string>));
  }

  public MyClass(SerializationInfo info, StreamingContext context)
  {
    MyClass.dict= (Dictionary<long, string>)info.GetValue("static.dic", 
       typeof(Dictionary<long, string>));

  }
  public void Add()
  {
    dict.Add(21, "11");
  }

  public MyClass()
  {
    dict.Add(21, "11");
  }
}


  public class MyClass 
  {       
        MyClass myClass = new MyClass();

        public static void Main()
        {
           myClass.Add();

           FileStream fileStream = new FileStream("test.binary", FileMode.Create);

           IFormatter  bf = new BinaryFormatter();

           bf.Serialize(fileStream, myClass);

            fileStream.Dispose();

            fileStream.Close();

            fileStream = new FileStream("test.binary", FileMode.Open);

            bf = new BinaryFormatter();

            myClass = (MyClass1)bf.Deserialize(fileStream);
     }
}

4 个答案:

答案 0 :(得分:4)

当您可以轻松发布显示问题的工作代码时,请不要发布“伪代码”。

无论如何,在清理完代码后,它按预期工作,因为反序列化对象会给我一个包含2个元素的字典。我打赌这个问题与你的静态字段dict有关。你不应该使用那样的静态字段。

您可以尝试以下代码并告诉我们问题是什么吗?这是工作代码,您可以将其粘贴到控制台或winforms应用程序的Program.cs文件中并进行调试。

请注意以下事项:

  • 我删除了dict字段的静态
  • 我修改了您用于添加的两个元素的键(两者都不能是21)
  • 我重命名了一个MyClass类,并修复了对MyClass1的引用
  • 我稍微重写了主要代码以使用using阻止,而不是调用.Close().Dispose()

以下是代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Test
{
    [Serializable]
    public class MyClass : ISerializable
    {
        internal Dictionary<long, string> dict = new Dictionary<long, string>();

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("static.dic", dict, typeof(Dictionary<long, string>));
        }

        public MyClass(SerializationInfo info, StreamingContext context)
        {
            dict = (Dictionary<long, string>)info.GetValue("static.dic",
               typeof(Dictionary<long, string>));
        }

        public void Add()
        {
            dict.Add(31, "11");
        }

        public MyClass()
        {
            dict.Add(21, "11");
        }
    }

    public class MyClassTest
    {
        public static void Main()
        {
            MyClass myClass = new MyClass();
            myClass.Add();

            using (FileStream fileStream = new FileStream("test.binary", FileMode.Create))
            {
                IFormatter bf = new BinaryFormatter();
                bf.Serialize(fileStream, myClass);
            }

            using (FileStream fileStream = new FileStream("test.binary", FileMode.Open))
            {
                IFormatter bf = new BinaryFormatter();
                myClass = (MyClass)bf.Deserialize(fileStream);
            }
        }
    }
}

答案 1 :(得分:1)

这基本上是完全错误的。

您正在尝试将实例的序列化/反序列化与类的静态状态的修改链接起来。

如果它与实例链接,则不应该是静态。

如果您希望与多个实例共享此词典状态,则它必须是不可变的(因此创建一个不会影响其他实例)。一个不错的不可变映射将使这变得容易(允许共享尽可能多的共享状态)

答案 2 :(得分:1)

几乎可以肯定不应该是静态的!

但;假设它是实例数据,您是否尝试添加调用OnDeserialization的{​​{1}}回调?

在你这样做之前,它可能是不完整的......

有关示例,请参阅here

答案 3 :(得分:0)

您不希望为此使用静态类。您想要使用在第一次创建时加载的单例。你可能还想要一个刷新方法。