views:

46

answers:

2

In C# I wish to serialise a data structure where objects can belong to more than one collection.

For example, I have a Person class. I also have a Family class and School class, which each contain a MemberList. An instance of the Person class can be present in both the MemberList of the Family and the School.

I wish to serialise the entire data structure but am concerned that the instance of the Person class will end up being stored as two separate instances and upon deserialisation I will end up with two instances instead of one. Is the serialiser clever enough to store the data so that this will not happen? Is there any way to stop this happening if so?

Any help or suggestions appreciated.

+1  A: 

It will serialize the entire object graph, to my knowledge - so object instances will be duplicated. Custom serialization is the only option, either manually or by overriding the default serialization of an object - both are involved.

I wouldn't worry about it too much, not until it becomes an issue anyway. First pass it will be fine to serialize the entire graph.

Adam
A: 

You could use the DataContractSerializer (which is used by WCF) and decorate each class (Family and School) with the DataContract attribute and the 'IsReference' property set to true, like so:

[DataContract(IsReference=true)]
pubic class Family
{

This will tell the DataContractSerializer to keep the references intact when recreating the object graph on deserialization.

You can serialize the object 'objectInstance' to a stream with DataContractSerializer like so:

using (var stream = new MemoryStream())
{ 
    var serializer = new DataContractSerializer(objectInstance.GetType());
    serializer.WriteObject(stream, objectInstance);

    // The object has now been serialized to the stream
    // Do something with the stream here.
}

Note that you don't actually have to use WCF, you can just use the DataContractSerializer to serialize/deserialize the object graph.

You can read more about this attribute on MSDN here.

Also, here is a basic example of how to use the 'IsReference' property.

Sam
Thanks very much, that second link is fantastic!
Caustix
Glad it helped! Just be wary that the DataContractSerializer will essentially serialize to XML (it is intended to be included in a SOAP message), so the serialized format will not be as small as other serializers. However, you easily can use GZIP compression ( System.IO.Compression.GZipStream) to minimize the serialized format before you store it.
Sam