views:

747

answers:

4

Hi,

I have a static generic dictionary in a class. As static memeber cannot serialized so i have implented ISerializable interface and method GetObjectData to serialize. I have a constructor which will also accept SerializationInfo and StreamingContext to deserliaze the dictionay. Now when i try to serialize and deserialize , it always return 1(thoug i added 2 entries). please find the pseduo code-

[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);
     }
}
+1  A: 

This is fundamentally completely wrong.

You are attempting to link the serialization/deserialization of an instance with modification of the static state of a class.

This should not be static state if it is linked with an instance.

If you wish to share this dictionaries state with multiple instances then it must be immutable (so that the creation of one does not affect the others). A decent immutable Map will make this easy (allowing sharing of as much shared state as possible)

ShuggyCoUk
+1  A: 

It almost certainly shouldn't be static!

But; assuming it is instance data, have you tried adding an OnDeserialization callback that calls dict.OnDeserialization?

Until you do that, it may be incomplete...

For an example, see here.

Marc Gravell
+1  A: 

Never post "pseudo-code" when you can just as easily post working code that exhibits the problem.

Anyway, after cleaning up your code, it works as expected, in the sense that deserializing the object gives me a dictionary with 2 elements. I'm betting the problem is related to your static field dict. You shouldn't use static fields like that.

Can you try the following code and tell us what the problem is? This is working code in the sense that you can paste this into the Program.cs file of a console or winforms application and debug it.

Note the following things:

  • I removed the static'ness of the dict field
  • I fixed the keys you used for the two elements you added (both can't be 21)
  • I renamed one of the MyClass classes, and fixed references to MyClass1
  • I rewrote the Main code slightly to use using block instead of calls to .Close() and .Dispose().

Here's the code:

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);
            }
        }
    }
}
Lasse V. Karlsen
thnx for your replies. i m using static dictionary bcoz my dictionay holds 20000 values so i don't want to call my sp again if my class gets intialize next time. i also want to add new entry into dictionary when user try to save a new entry. i know serialize static object is flaw design but in this case i have to declare dict as static otherwise it uwd be huge perofmance overhead. lasse ur code works ,but can u tell me y count of dict returns zero when ym constructor gets called.(at time of deserialize)
Lassse , is there any way tht i can achive basic and mixed serialization together , bcoz i only need dictionay to implement custom while other member of class can be serialized in a basic/normal way.
A: 

You don't want to use static class for this. You want to use a singleton that loads on the first creation. You may also want a refresh method on there.

lkeel