Reputation: 11430
I am trying to learn to use C# serialization as a way to save objects into files that can be reloaded back into objects.
A plain class like this that I tested
[Serializable()]
public class PlainClass
{
public string Name;
private int Age;
protected decimal Price;
}
Can be directly BinaryFormatter.Serialize() and BinaryFormatter.Deserialize() without errors. (by the way, the private and protected properties also get serialized although the docs say only public)
But the moment it implements ISerialization or inherit some class like Hashtable that implements ISerialization, the you-know-what deserialization constructor is required. The word or concept of "implement" becomes a misnomer because Hashtable does not actually implement that constructor.
Is there a way to fall back to the "auto" Serialization/Deserialzation provided only by the attribute? Or is there an easier way to write info.GetValue() for a hundred properties in a class?
Upvotes: 3
Views: 1647
Reputation: 70379
Hashtable/Dictionary requires the implementation of the respective methods...
To work around that you would have to implement a separate class to hold the Dictionary data and provide an IList interface instead which in turn need not work on TKeyValuePair but with a separately implemented class with Key/Value (refer to http://blogs.msdn.com/b/adam/archive/2010/09/10/how-to-serialize-a-dictionary-or-hashtable-in-c.aspx)...
As you can see from the start of my explanation - this is nothing you would usually want to do...
There are better serialization solutions out there - see for a very good one http://code.google.com/p/protobuf-net/
Upvotes: 0
Reputation: 1063774
There is a lot of confusion in your post:
by the way, the prive and protected properties also get serialized although the docs say only public)
I suspect you are confusing two different serializers; BinaryFormatter
is and always has been documented as field-centric. It doesn't distinguish between public/private, and it never looks at properties: only fields. XmlSerializer
, by contrast, only looks at public properties and fields.
The word or concept of "implement" becomes a misnomer because Hashtable does not actually implement that constructor.
Yes it does; it is a protected
constructor:
protected Hashtable(SerializationInfo info, StreamingContext context)
{...}
If you inherit Hashtable
you can chain to this constructor:
protected YourType(SerializationInfo info, StreamingContext context)
: base(info, context)
{ /* your extra data */ }
Note, however, that you probably shouldn't be using Hashtable
much unless you are on .NET 1.1.
Is there a way to fall back to the "auto" Serialization/Deserialzation provided only by the attribute?
No; none.
Or is there an easier way to write info.GetValue() for a hundred properties in a class?
In the case of inherited data, you could chain the base-constructor or switch to encapsulation instead of inheritance - either avoids the need to worry about data other than your own.
Note, however, that I almost always guide against BinaryFormatter
- it can be vexing, and is quirky with versioning. For every annoyance with BinaryFormatter
, I use protobuf-net (I would, since I wrote it) - this generally makes serialization much more controlled (and more efficient), and includes an ISerializable
hook if you really want to use BinaryFormatter
(i.e. it can use BinaryFormatter
as the wrapper, but with a protobuf-net payload).
Upvotes: 4