|
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++
|
|
|
|
|
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++
|
|
|
|
|
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++
|
|
|
|
|
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++
|
|
|
|
|
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.
|
|
|
|
|
I was trying to convince myself more than you I think
I knew I read it somewhere once, and testing confirmed it.
Its obscurely "documented" here[^].
I appreciate the discussion, thanks!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
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...
|
|
|
|
|
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++
|
|
|
|
|
Well, the debugger shows "Animal {Dog}" as type for dogAsAnimal . a yields "Animal" and d yields "Dog", so I expected dogAsAnimal to be an Animal -type reference to an object that is Dog .
It's the same with a direct cast.
I cannot access the Dog -only properties of dogAsAnimal , but the BinaryFormatter 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++
|
|
|
|
|
Thanks for the suggestion, I'll take a look.
Jeez, I didn't expect it to get so complicated...
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] <code>
public Int32 A;
[NonSerialized] <code>
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";
}
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();
BinaryFormatter Serializer = new BinaryFormatter();
Serializer.Serialize(MemStream, dog);
MemStream.Seek(0, SeekOrigin.Begin);
Serializer.Binder = new DogToAnimalDeserializationBinder();
Animal animal = (Animal)Serializer.Deserialize(MemStream);
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
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 in BindToType , then the deserializing end doesn't require knowledge about Dog , but unfortunately it doesn't work because then even Animal 's properties aren't deserialized if I have a Dog 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++
|
|
|
|
|
I think I got it!
After your and Giorgi's hints concerning the SerializationBinder , I looked at BinaryFormatter 's other properties and found SurrogateSelector and subsequently ISerializationSurrogate .
Using these two interfaces I was able to control the serialization process in a way that only Animal 's properties are being serialized and during deserialization a real Animal 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++
|
|
|
|
|
I'm writing my first VSTO Outlook add-in. Basically "Hello World". It's VS 2008 targeting Outlook 2007. It's a standard MS VS build/publish.
In the startup handler I've got:
try
{
Office.CommandBar commandBar = activeExplorer.CommandBars["Standard"];
button = (Office.CommandBarButton)commandBar.Controls.Add(1, missing, missing, missing, missing);
button.Style = Office.MsoButtonStyle.msoButtonCaption;
button.Caption = "TEST";
button.Tag = "btnProcess";
return true;
}
catch (ArgumentException e)
{
MessageBox.Show(e.Message);
}
'button' is a local Office.CommandBarButton object.
It installs nicely and puts a 'TEST' button on the standard toolbar as expected. But when I uninstall via Control Panel, the button is still there when I restart Outlook.
I guess I need something in the shutdown handler to kill the button - but what? Office.CommandBarButton class does not have a dispose event. How come the button is still there after uninstallation, and how do I solve that? I'm a bit confused here. Help!
JustAStupidGurl
|
|
|
|
|
Hi My Friends,
I need free C# TreeList code that will run on the web.
ASAP please. Thanks.
|
|
|
|
|
inerp wrote: ASAP please. Thanks.
hahaha... *breath* good one.
Im sorry, but we dont write code for you. Can I suggest heading over to rentacoder.com or google. take your pick.
|
|
|
|
|
Just leave your e-mail and whole codeproject community will send the code immediately.
|
|
|
|