BinaryFormatter: Serializing an object's base class
-
I will believe you on the second one, however, a default constructor is defined by default unless you create either a non-default constructor or a default constructor with visibility other than public. See: http://support.microsoft.com/kb/330592[^]
public class Foo{
}
and
public class Foo{
public Foo(){}
}Both contain default constructors whereas
public class Foo{
public Foo(int a){}
}and
public class Foo{
private Foo(){}
}Do not.
Need software developed? Offering C# development all over the United States, ERL GLOBAL, Inc is the only call you will have to make.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway
Most of this sig is for Google, not ego.Also, the constructor is only called when using XmlSerializer. No constructor is called with binary/SOAP deserialization. Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Also, the constructor is only called when using XmlSerializer. No constructor is called with binary/SOAP deserialization. Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
I didn't know that, I just assumed a constructor would be called.
Need software developed? Offering C# development all over the United States, ERL GLOBAL, Inc is the only call you will have to make.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway
Most of this sig is for Google, not ego. -
What if you make the Dog class [Serializable], mark all its members [NonSerialized], and use a SerializationBinder[^] for deserialization? I'm not sure if it will work or not :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
Thanks for the suggestion, I'll take a look. Jeez, I didn't expect it to get so complicated... ;P
Regards, mav -- Black holes are the places where God divided by 0...
-
I didn't know that, I just assumed a constructor would be called.
Need software developed? Offering C# development all over the United States, ERL GLOBAL, Inc is the only call you will have to make.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway
Most of this sig is for Google, not ego. -
Thanks for the suggestion, I'll take a look. Jeez, I didn't expect it to get so complicated... ;P
Regards, mav -- Black holes are the places where God divided by 0...
I was bored, so I tried it. Works great :)
\[Serializable\] public class Animal { public string str { get; set; } } \[Serializable\] public class Dog : Animal { \[NonSerialized\] `//<-- Optional!` public Int32 A; \[NonSerialized\] `//<-- Optional!` public Int32 B; public Dog() { A = 5; B = 10; } } sealed class DogToAnimalDeserializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { Type typeToDeserialize = null; String assemVer1 = Assembly.GetExecutingAssembly().FullName; String typeVer1 = "Dog"; if (assemblyName == assemVer1 && typeName == typeVer1) { typeName = "Animal"; } // The following line of code returns the type. typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName)); return typeToDeserialize; } }
...
Dog dog = new Dog();
dog.A = 3;
dog.B = 5;
dog.str = "Animal String";MemoryStream MemStream = new MemoryStream();
// Serialize a Dog object
BinaryFormatter Serializer = new BinaryFormatter();
Serializer.Serialize(MemStream, dog);MemStream.Seek(0, SeekOrigin.Begin);
// Deserialize as an Animal object
Serializer.Binder = new DogToAnimalDeserializationBinder();
Animal animal = (Animal)Serializer.Deserialize(MemStream);Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Thanks for the suggestion, I'll take a look. Jeez, I didn't expect it to get so complicated... ;P
Regards, mav -- Black holes are the places where God divided by 0...
Wow - my code was overcomplicated. The Binder there is completely unnecessary :rolleyes:
mav.northwind wrote:
The other side of the line (where the object is supposed to be deserialized) doesn't know about Dogs, it only knows about Animals (i.e. there's only the assembly defining Animal available, not the one defining Dog, so trying to deserialize this object will throw a TypeLoadException).
I just noticed that post. The only way that's going to work is to serialize an Animal object in the first place, as you already know. The deserializing end could use a custom binder to deserialize a Dog, but that would still require that end to have the assembly implementing the Dog class. Basically I helped get you back where you started, sorry! :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Wow - my code was overcomplicated. The Binder there is completely unnecessary :rolleyes:
mav.northwind wrote:
The other side of the line (where the object is supposed to be deserialized) doesn't know about Dogs, it only knows about Animals (i.e. there's only the assembly defining Animal available, not the one defining Dog, so trying to deserialize this object will throw a TypeLoadException).
I just noticed that post. The only way that's going to work is to serialize an Animal object in the first place, as you already know. The deserializing end could use a custom binder to deserialize a Dog, but that would still require that end to have the assembly implementing the Dog class. Basically I helped get you back where you started, sorry! :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
Hmmm, I've played around with the SerializationBinder a bit, but didn't get a useable result either. If I always return
typeof(Animal)
as target type inBindToType
, then the deserializing end doesn't require knowledge aboutDog
, but unfortunately it doesn't work because then evenAnimal
's properties aren't deserialized if I have aDog
object in my serialization stream. :(Regards, mav -- Black holes are the places where God divided by 0...
-
See if this helps: Advanced Binary Serialization: Deserializing an Object Into a Different Type Than the One It was Serialized Into[^]
Giorgi Dalakishvili #region signature My Articles / My Latest Article[^] / My blog[^] #endregion
Thanks for the link, it was quite instructive, although I couldn't achieve useable results so far with a SerializationBinder... Nevertheless: thanks for taking your time.
Regards, mav -- Black holes are the places where God divided by 0...
-
Hmmm, I've played around with the SerializationBinder a bit, but didn't get a useable result either. If I always return
typeof(Animal)
as target type inBindToType
, then the deserializing end doesn't require knowledge aboutDog
, but unfortunately it doesn't work because then evenAnimal
's properties aren't deserialized if I have aDog
object in my serialization stream. :(Regards, mav -- Black holes are the places where God divided by 0...
Right. The only way I can see to do it, if the deserialization end has no access to the Dog class (or an equivalent class), is to add a method to Dog that returns an Animal object and serialize that object. It's really unconventional anyway....it generally doesn't make sense to only serialize the base class portion of an object. But if you have a special need I suppose you need a special solution. :) Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Right. The only way I can see to do it, if the deserialization end has no access to the Dog class (or an equivalent class), is to add a method to Dog that returns an Animal object and serialize that object. It's really unconventional anyway....it generally doesn't make sense to only serialize the base class portion of an object. But if you have a special need I suppose you need a special solution. :) Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
I think I got it! After your and Giorgi's hints concerning the
SerializationBinder
, I looked atBinaryFormatter
's other properties and foundSurrogateSelector
and subsequentlyISerializationSurrogate
. Using these two interfaces I was able to control the serialization process in a way that onlyAnimal
's properties are being serialized and during deserialization a realAnimal
object is being created. This should do the trick... Thanks for taking your time!Regards, mav -- Black holes are the places where God divided by 0...
-
I think I got it! After your and Giorgi's hints concerning the
SerializationBinder
, I looked atBinaryFormatter
's other properties and foundSurrogateSelector
and subsequentlyISerializationSurrogate
. Using these two interfaces I was able to control the serialization process in a way that onlyAnimal
's properties are being serialized and during deserialization a realAnimal
object is being created. This should do the trick... Thanks for taking your time!Regards, mav -- Black holes are the places where God divided by 0...
Very cool! Thanks for the update! Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java: