Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Serializing, add new member var problem.

Serializing, add new member var problem.

Scheduled Pinned Locked Moved C#
helptutorialquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Steve Schaneville
    wrote on last edited by
    #1

    I have a class that serializes itself out to a file using the SoapFormatter class. I have now added a new member variable to the class and want it to be serializeable too. But loading the previously saved file fails because this new member is not available in the saved file. If I set the new member to non-serializeable, the load works fine but then I can't save that member back out on the next save operation. Any ideas how to get around this problem without throwing my save file away and starting from scratch? Thanks! ~Steve

    T H 2 Replies Last reply
    0
    • S Steve Schaneville

      I have a class that serializes itself out to a file using the SoapFormatter class. I have now added a new member variable to the class and want it to be serializeable too. But loading the previously saved file fails because this new member is not available in the saved file. If I set the new member to non-serializeable, the load works fine but then I can't save that member back out on the next save operation. Any ideas how to get around this problem without throwing my save file away and starting from scratch? Thanks! ~Steve

      T Offline
      T Offline
      turbochimp
      wrote on last edited by
      #2

      Does your class implement the ISerializable interface? If so, you can override the ISerializable.GetObjectData method as well as the deserialization constructor to handle situations where the graph does not contain one or more fields that exist in the class. Note that the type still needs the [Serializable] attribute even when implementing ISerializable. Hope this helps.

      The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’

      S 1 Reply Last reply
      0
      • S Steve Schaneville

        I have a class that serializes itself out to a file using the SoapFormatter class. I have now added a new member variable to the class and want it to be serializeable too. But loading the previously saved file fails because this new member is not available in the saved file. If I set the new member to non-serializeable, the load works fine but then I can't save that member back out on the next save operation. Any ideas how to get around this problem without throwing my save file away and starting from scratch? Thanks! ~Steve

        H Offline
        H Offline
        Heath Stewart
        wrote on last edited by
        #3

        In addition to what the 'chimp said, there's actually a better way that is verion-independent. First, if you correctly version your assemblies (as you should, just don't use automatic versioning a la an asterisk in your [assembly: AssemblyVersionAttribute]) you'll have another problem: the serialized form won't deserialize into a newer version (the types don't match, because the versions are different). This is where a SerializationBinder comes into play. You extend the SerializationBinder and override BindToType. This gives you a chance to "redirect" versions. What I typically do is take the assembly string (includes name, version, culture info, and public key token) and strip out everything but the version. I then concat the typename and left-over assembly name to get a version-independent type. When you then get the Type, the latest version of the assembly is loaded and the new Type is returned. This new version of your existing class would contain the new field (not "variable", which is declared within a method itself), so you may still have to use the 'chimp's suggestion of implementing ISerializable (typically a good idea when you want better control over serialization anyway). Below is a snippet of code showing what I mentioned:

        public class DiffVersionBinder : SerializationBinder
        {
        public override Type BindToType(string assemblyName, string typeName)
        {
        string name = assembly.Name.Substring(0, assemblyName.IndexOf(','));
        Type t = Type.GetType(typeName + ", " + name);
        return t;
        }
        }

        To use:

        IFormatter formatter = new SoapFormatter();
        formatter.Binder = new DiffVersionBinder();
        object obj = formatter.Deserialize(someStream);

        Microsoft MVP, Visual C# My Articles

        S 1 Reply Last reply
        0
        • T turbochimp

          Does your class implement the ISerializable interface? If so, you can override the ISerializable.GetObjectData method as well as the deserialization constructor to handle situations where the graph does not contain one or more fields that exist in the class. Note that the type still needs the [Serializable] attribute even when implementing ISerializable. Hope this helps.

          The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’

          S Offline
          S Offline
          Steve Schaneville
          wrote on last edited by
          #4

          Hey, sorry for not replying to say "thanks". I had found a solution shortly after I posted and then completely forgot that I posted! Thanks for the info... good stuff. ~Steve

          1 Reply Last reply
          0
          • H Heath Stewart

            In addition to what the 'chimp said, there's actually a better way that is verion-independent. First, if you correctly version your assemblies (as you should, just don't use automatic versioning a la an asterisk in your [assembly: AssemblyVersionAttribute]) you'll have another problem: the serialized form won't deserialize into a newer version (the types don't match, because the versions are different). This is where a SerializationBinder comes into play. You extend the SerializationBinder and override BindToType. This gives you a chance to "redirect" versions. What I typically do is take the assembly string (includes name, version, culture info, and public key token) and strip out everything but the version. I then concat the typename and left-over assembly name to get a version-independent type. When you then get the Type, the latest version of the assembly is loaded and the new Type is returned. This new version of your existing class would contain the new field (not "variable", which is declared within a method itself), so you may still have to use the 'chimp's suggestion of implementing ISerializable (typically a good idea when you want better control over serialization anyway). Below is a snippet of code showing what I mentioned:

            public class DiffVersionBinder : SerializationBinder
            {
            public override Type BindToType(string assemblyName, string typeName)
            {
            string name = assembly.Name.Substring(0, assemblyName.IndexOf(','));
            Type t = Type.GetType(typeName + ", " + name);
            return t;
            }
            }

            To use:

            IFormatter formatter = new SoapFormatter();
            formatter.Binder = new DiffVersionBinder();
            object obj = formatter.Deserialize(someStream);

            Microsoft MVP, Visual C# My Articles

            S Offline
            S Offline
            Steve Schaneville
            wrote on last edited by
            #5

            Hey, sorry for not replying to say "thanks". I had found a solution shortly after I posted and then completely forgot that I posted! Thanks for the info... good stuff. ~Steve

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups