What is sharpSerializer?
sharpSerializer is an open source XML and binary serializer for .NET Framework, Silverlight, Windows Phone, Windows RT (Metro) and Xbox360
Why sharp? Because was developed with C#. Why Serializer? Because it should primarily replace the built in XmlSerializer
. Actually sharpSerializer can serialize to Xml and to its own binary format. However after providing it with custom writers, it can serialize data to other text formats like Json or other encrypted, compressed, optimized etc. binary streams. Since the v.2.20. it is deployed additionally as Portable Library
and it can work on .NET 2.0 and above, Silverlight 3 and above, Windows Phone 7 and above, Windows RT and Xbox 360.
If you are tired of marking your data model with plenty of attributes, or passing in advance to your current serializer all the types you could ever serialize - there is a solution - a free tool for such an easy and quick object serialization.
Why is sharpSerializer better then the XmlSerializer?
sharpSerializer can serialize everything what the XmlSerializer can, but easier. Additionaly it offers some extra features.
|Types to serialize
|Multidimensional arrays, nested arrays, array-of-arrays
|Polymorphic properties (where property value is inherited from the property type - is its subtype)
|Generic types with polymorphic arguments (i.e. MyGenericClass<AbstractArgumentClass>)
|Generic listings (i.e. Dictionary<K,T>)
|Polymorphic listings (Collection, Dictionary, single dimensional array, multidimensional array)
|Listings of generic types with polymorphic arguments (i.e. an array IMyGenericInterface<MyAbstractClass>[,,])
It does not matter, how many dimensions or nested arrays an array has, 1,2,3...8. As the element type there can be a primitive type, complex object, generic type or nested collection - sharpSerializer can serialize all of them.
There is property of type IMyInterface
in a class. But as the property value contains an instance of a class MyClass
, which implements IMyInterface
. This is the polymorphic property. XmlSerializer
could serialize such a property, only if provided in advance with the both types (IMyInterface
) in its Serialize() method. sharpSerializer can serialize such an object without additional type definitions nor marking your model with attributes.
Generic types with polymorphic arguments
Some generic class of type MyGenericClass<AbstractDataClass>
contains an instance of RealDataClass
which is inherited from the AbstractDataClass
. This is a polymorphic argument, which the sharpSerializer can automatic detect and serialize.
With sharpSerializer you can serialize generic Dictionary<K,T>
are of a complex type or even nested dictionary.
There is a dictionary of type Dictionary<IKeyInterface, AbstractValueClass>
where keys are inherited from IKeyInterface
and values are inherited from AbstractValueClass
. We say - the keys and values are polymorphic. sharpSerializer can serialize it as a normal dictionary.
Listings of generic types with polymorphic arguments
Imagine a multidimensional array IMyGenericInterface<MyAbstractClass>[,,]
. Who needs such a weird type at all? Never mind! sharpSerializer can serialize it too.
Why is sharpSerializer better than the BinaryFormatter?
For Silverlight programmers the benefit is clear - there is no BinaryFormatter
in Silverlight at all ;-)
A significant drawback of BinaryFormatter
in .NET Full is throwing an exception during deserialization if there are unknown properties in the deserialized stream. SharpSerializer since v.2.20 ignores these properties and can be used as a data storage.
The built in the full .NET Framework BinaryFormatter
can serialize only classes which are marked with SerializableAttribute
, or implement ISerializable
. As mentioned above - sharpSerializer needs no extra attributes for serializing.
The following small test program
(VS2010) measures serialization speed and size of the output file. Serialized was an array of 10 000 elements of type RootContainer
. This is almost the same class as in the HelloWorld example
- It's only extended with [Serializable
] to all of its subclasses ;-)
The following table presents the serialization results (sharpSerializer v.2.6):
|Serialization time [s]
|Deserialization time [s]
|sharpSerializer - binary (Burst)
|sharpSerializer - binary (SizeOptimized)
|sharpSerializer - Xml
As you can see, the fastest serialization of 2.1s offers BinaryFormatter, but its filesize of 19.3MB is twice as big as produces sharpSerializer in the binary SizeOptimized mode. Deserialization time of BinaryFormatter is over 3 times longer than the best time 2.6s of sharpSerializer. Be honest and tell me - who is the winner?
How does sharpSerializer work?
Serialization contains of three steps:
- PropertyFactory converts source object to a Property class. The Property together with its nested Properties mirrors the internal object structure. Xml serialization and binary serialization use the same routine to extract properties from the serialized object and convert them into the Property.
- The Property is passed as an argument to IPropertySerializer.Serialize() method. When IPropertySerializer contains an instance of XmlPropertySerializer, it serializes the object into a tree oriented structure, where every element has its beginning and end, like xml. Alternatively it serializes the object into a fixed set of elements of a known length, i.e. a binary stream. In this case as IPropertySerializer operates BinaryPropertySerializer. Neither XmlPropertySerializer nor BinaryPropertySerializer knows in what format the data is stored. Storing the data as bits and bytes is responsibility of IXmlWriter or IBinaryWriter.
- IPropertySerializer invokes storage commands on correlated IXmlWriter or IBinaryWriter. DefaultXmlWriter stores data into Xml whereas BurstBinaryWriter or SizeOptimizedBinaryWriter uses binary format.
Deserialization is a symmetric process. First IXmlReader
reads the data from the stream. Then the data is deserialized by the IPropertyDeserializer
into an instance of a Property
class. The Property
is passed as a parameter to the ObjectFactory.CreateObject()
method which in turn converts it into a target object.
What can sharpSerializer serialize?
Out of the box sharpSerializer can serialize all properties which:
- are public
- are not static
- have their set and get accessors
- are not indexers
- are not marked with ExcludeFromSerializationAttribute
- are not listet in SharpSerializer.PropertyProvider.PropertiesToIgnore
Why only properties? Because it's quicker to serialize only properties and still enough to persist an object's state.
What can't sharpSerializer serialize?
In the current version of sharpSerializer there are some restrictions concerning serialization and deserialization of objects. In the future these restrictions can be neutralized, but actually they make no such pain. These are:
- sharpSerializer can't deserialize types without public, standard constructor.
- it cannot serialize fields.
These restrictions can be neutralized by using substitution pattern.
Following restriction concerns serialization in Silverlight and Portable Library:
- it can't deserialize LowerBound of an array. In such case the LowerBound is set to 0 during deserialization.
LowerBound of an array is not part of Silverlight and therefore can not be handled by the sharpSerializer.
Does the world need one more serializer?
There are three reasons, why I started developing sharpSerializer:
- Few years ago I have been struggling with a polymorphic configuration. My purpose was - to save application configuration in a single XML file. I needed a lightweight configuration storage with support for object inheritance. The file should be easily readable and manually editable. The System.Configuration has big overhead and is too stiff.
- Almost every application needs repository for its data. With SharpSerializer I can freely define my data objects with no need to define database fields in advance, or reconfigure the O/R Mapper every time the model changes.
- Silverlight and especially WP7 (Windows Phone 7) has poor support for the local data repository with its XML DataContractSerializer. Even worse - it has no support for the binary serialization at all. SharpSerializer can tombstoning in binary and XML way. From now on it's very simple to store application data into isolated storage or serialize data and send it as binary or XML between .NET Full, Silverlight or other devices like Windows Phone, Windows RT or Xbox 360
Quo vadis sharpSerializer?
There are plenty of features which could be implemented in sharpSerializer, like:
- custom binary writers with support for encryption, compression, checksum control
- custom writers with support for other popular formats, like Json
- porting of sharpSerializer to Mono and other plattforms
Everything depends on the demand and eventual popularity of sharpSerializer. The Framework is young yet, therefore each feedback is appreciated, every contributor is welcome, as I'm actually under pressure with other projects.