BinaryFormatter: Serializing an object's base class
-
bf.Serialize(serializationStream, **(Animal) d**);
?It doesn't matter whether I use
as
or an explicit cast. In the real code I had a methodToFile(Animal a, string path)
and it also showed the effect. The debugger does show that it's anAnimal
reference in every case.Regards, mav -- Black holes are the places where God divided by 0...
-
Hi! I just stumbled over an unexpected behaviour when trying to serialize a derived class using a
BinaryFormatter
, I guess the best is to show in code://for this sample I have 2 classes:
// [Serializable] class Animal
// and
// class Dog : Animal
// (not serializable)
Animal a = new Animal();
Dog d = new Dog();
Animal dogAsAnimal = d as Animal;BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(serializationStream, a); // works
// bf.Serialize(serializationStream, d); // throws an exception because Dog is not Serializable
bf.Serialize(serializationStream, dogAsAnimal); // <- throws exception as wellI can't really understand why the last line is trying to serialize the object as Dog instead of Animal - is there any way to keep BinaryFormatter from doing this (short of adding a copy constructor to Animal and actually creating a new object)? Thanks in advance!
Regards, mav -- Black holes are the places where God divided by 0...
The derived class also has to be serializable. I think you'll also find that only protected and public vars will be serialized from the base class, but I'm just guessing at that.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001 -
The derived class also has to be serializable. I think you'll also find that only protected and public vars will be serialized from the base class, but I'm just guessing at that.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001But that's something I explicitely do not need/want. Of course I could flag
Dog
asSerializable
, too, but then the object is serialized asDog
, not asAnimal
. The other side of the line (where the object is supposed to be deserialized) doesn't know aboutDog
s, it only knows aboutAnimal
s (i.e. there's only the assembly definingAnimal
available, not the one definingDog
, so trying to deserialize this object will throw aTypeLoadException
).Regards, mav -- Black holes are the places where God divided by 0...
-
But that's something I explicitely do not need/want. Of course I could flag
Dog
asSerializable
, too, but then the object is serialized asDog
, not asAnimal
. The other side of the line (where the object is supposed to be deserialized) doesn't know aboutDog
s, it only knows aboutAnimal
s (i.e. there's only the assembly definingAnimal
available, not the one definingDog
, so trying to deserialize this object will throw aTypeLoadException
).Regards, mav -- Black holes are the places where God divided by 0...
Well, it appears from your code sample as if you really want to serialize the Dog object. I don't understand why you wouldn't want to do that, since you can Deserialize it and cast it back to animal if that's what you really need. Why in the world would the deserialize code not know about the dog object. It looks from here as if your design needs to be re-engineered.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001 -
Hi! I just stumbled over an unexpected behaviour when trying to serialize a derived class using a
BinaryFormatter
, I guess the best is to show in code://for this sample I have 2 classes:
// [Serializable] class Animal
// and
// class Dog : Animal
// (not serializable)
Animal a = new Animal();
Dog d = new Dog();
Animal dogAsAnimal = d as Animal;BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(serializationStream, a); // works
// bf.Serialize(serializationStream, d); // throws an exception because Dog is not Serializable
bf.Serialize(serializationStream, dogAsAnimal); // <- throws exception as wellI can't really understand why the last line is trying to serialize the object as Dog instead of Animal - is there any way to keep BinaryFormatter from doing this (short of adding a copy constructor to Animal and actually creating a new object)? Thanks in advance!
Regards, mav -- Black holes are the places where God divided by 0...
Objects have to have public, empty constructors to be serialization using the built in methods (Don't quote me) and need to have the Serialization attribute as well as the ISerializable interface for binary serialization. Base classes, in general, can't be serialized if they can't be instantiated.
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. -
Well, it appears from your code sample as if you really want to serialize the Dog object. I don't understand why you wouldn't want to do that, since you can Deserialize it and cast it back to animal if that's what you really need. Why in the world would the deserialize code not know about the dog object. It looks from here as if your design needs to be re-engineered.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001The simplest explanation for what mav's doing is that animal is owned by a different team and are either unwilling or unable to modify the object to contain additional functionality that is needed in mav's part of the project. For every part of the app except serialization having dog inherit from animal makes a more natural design than having dog have an animal member.
Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots. -- Robert Royall
-
Hi! I just stumbled over an unexpected behaviour when trying to serialize a derived class using a
BinaryFormatter
, I guess the best is to show in code://for this sample I have 2 classes:
// [Serializable] class Animal
// and
// class Dog : Animal
// (not serializable)
Animal a = new Animal();
Dog d = new Dog();
Animal dogAsAnimal = d as Animal;BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(serializationStream, a); // works
// bf.Serialize(serializationStream, d); // throws an exception because Dog is not Serializable
bf.Serialize(serializationStream, dogAsAnimal); // <- throws exception as wellI can't really understand why the last line is trying to serialize the object as Dog instead of Animal - is there any way to keep BinaryFormatter from doing this (short of adding a copy constructor to Animal and actually creating a new object)? Thanks in advance!
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
-
Objects have to have public, empty constructors to be serialization using the built in methods (Don't quote me) and need to have the Serialization attribute as well as the ISerializable interface for binary serialization. Base classes, in general, can't be serialized if they can't be instantiated.
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.Ennis Ray Lynch, Jr. wrote:
Objects have to have public, empty constructors to be serialization using the built in methods
Not true. No constructor is used in deserialization AFAIK.
Ennis Ray Lynch, Jr. wrote:
Base classes, in general, can't be serialized if they can't be instantiated.
Huh? :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Hi! I just stumbled over an unexpected behaviour when trying to serialize a derived class using a
BinaryFormatter
, I guess the best is to show in code://for this sample I have 2 classes:
// [Serializable] class Animal
// and
// class Dog : Animal
// (not serializable)
Animal a = new Animal();
Dog d = new Dog();
Animal dogAsAnimal = d as Animal;BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(serializationStream, a); // works
// bf.Serialize(serializationStream, d); // throws an exception because Dog is not Serializable
bf.Serialize(serializationStream, dogAsAnimal); // <- throws exception as wellI can't really understand why the last line is trying to serialize the object as Dog instead of Animal - is there any way to keep BinaryFormatter from doing this (short of adding a copy constructor to Animal and actually creating a new object)? Thanks in advance!
Regards, mav -- Black holes are the places where God divided by 0...
dogAsAnimal is still a Dog object, regardless of the "cast". You can see that in the debugger. "as" doesn't create a new object of a different type. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
dogAsAnimal is still a Dog object, regardless of the "cast". You can see that in the debugger. "as" doesn't create a new object of a different type. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
Well, the debugger shows "Animal {Dog}" as type for
dogAsAnimal
.a
yields "Animal" andd
yields "Dog", so I expecteddogAsAnimal
to be anAnimal
-type reference to an object that isDog
. It's the same with a direct cast. I cannot access theDog
-only properties ofdogAsAnimal
, but theBinaryFormatter
seems to see through the cast and serialize the deepest inheritance.Regards, mav -- Black holes are the places where God divided by 0...
-
Ennis Ray Lynch, Jr. wrote:
Objects have to have public, empty constructors to be serialization using the built in methods
Not true. No constructor is used in deserialization AFAIK.
Ennis Ray Lynch, Jr. wrote:
Base classes, in general, can't be serialized if they can't be instantiated.
Huh? :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
For standard XML serializaiton the default constructor needs to be public. For binary serializaiton you need to have the serialization constructor defined.
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. -
Well, it appears from your code sample as if you really want to serialize the Dog object. I don't understand why you wouldn't want to do that, since you can Deserialize it and cast it back to animal if that's what you really need. Why in the world would the deserialize code not know about the dog object. It looks from here as if your design needs to be re-engineered.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001:) Well, things tend do become simplified when stripping the context. I have a system of several client applications and a server that are communicating via remoting. They all have a notion of
Animal
.Animal
has a methodpublic static void ToFile(Animal a, string file)
(and the correspondingFromFile()
). For a new client, aDog
class had to be created, but since this class is only used with this client it doesn't make sense to put it into the library definingAnimal
. Then the client wanted to serialize theAnimal
-part of one of theDog
objects using the staticAnimal.ToFile()
method, but the binary formatter threw an exception becauseDog
wasn't marked as serializable. The most intuitive method (for me) to solve this problem would be to find a way to tell the BinaryFormatter that what he gets really really is just anAnimal
, but I don't know how. Other solutions would be to use aggregation instead of inheritance, but that would require some rewriting of existing code. Or I could add a copy constuctor toAnimal
and actally create a new object, but that's not really the idea - I don't want to serialize a copy of aDog
, I only want to serialize theAnimal
-parts of the Dog...Regards, mav -- Black holes are the places where God divided by 0...
-
For standard XML serializaiton the default constructor needs to be public. For binary serializaiton you need to have the serialization constructor defined.
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.Ennis Ray Lynch, Jr. wrote:
For standard XML serializaiton the default constructor needs to be public
What if there's no default constructor?
Ennis Ray Lynch, Jr. wrote:
For binary serializaiton you need to have the serialization constructor defined.
Not true. That's only for ISerializable-derived classes. ISerializable isn't required for binary serialization.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Well, the debugger shows "Animal {Dog}" as type for
dogAsAnimal
.a
yields "Animal" andd
yields "Dog", so I expecteddogAsAnimal
to be anAnimal
-type reference to an object that isDog
. It's the same with a direct cast. I cannot access theDog
-only properties ofdogAsAnimal
, but theBinaryFormatter
seems to see through the cast and serialize the deepest inheritance.Regards, mav -- Black holes are the places where God divided by 0...
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:
-
Ennis Ray Lynch, Jr. wrote:
For standard XML serializaiton the default constructor needs to be public
What if there's no default constructor?
Ennis Ray Lynch, Jr. wrote:
For binary serializaiton you need to have the serialization constructor defined.
Not true. That's only for ISerializable-derived classes. ISerializable isn't required for binary serialization.
Mark Salsbery Microsoft MVP - Visual C++ :java:
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. -
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.Ennis Ray Lynch, Jr. wrote:
a default constructor is defined by default unless you create either a non-default constructor or a default constructor with visibility other than public.
Got it, thanks :) Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
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.