views:

798

answers:

4

When serializing, I would like to serialize an object only once, then any references to that object should be serialized as a reference to the object. This is because, when I later deserialize the objects, I would like to maintain those references. To illustrate my goal, the code below should output "After Serialization: true".

class Program
{
    static void Main(string[] args)
    {
        MyObject obj = new MyObject() { Name = "obj" };
        MyObject[] myObjs = new MyObject[]
        {
            obj, obj
        };

        Console.WriteLine("Object Refs Equal?");
        Console.WriteLine(string.Format("Before Serialization: {0}",
            object.ReferenceEquals(myObjs[0], myObjs[1])));

        XmlSerializer toXml = new XmlSerializer(typeof(MyObject[]));
        using (FileStream toFile = File.Create(@"C:\foo.xml"))
        {
            toXml.Serialize(toFile, myObjs);
        }

        XmlSerializer fromXml = new XmlSerializer(typeof(MyObject[]));
        using (FileStream fromFile = File.OpenRead(@"C:\foo.xml"))
        {
            MyObject[] deserialized = (MyObject[])fromXml.Deserialize(fromFile);

            Console.WriteLine(string.Format("After Serialization: {0}",
            object.ReferenceEquals(deserialized[0], deserialized[1])));
        }

        Console.ReadLine();
    }
}

[Serializable]
public class MyObject
{
    public string Name { get; set; }
}
A: 

You will have to do that by giving the objects identifiers other than their object reference.

An object's reference is essentially it's pointer. Since you cannot manipulate pointers directly in safe code must give the object some other unique name.

Jan Bannister
A: 

Not sure if this is what you would like to hear... But lets just think about what you are trying to do.

You only have the need to serialize an object when: a) You want to store it somewhere an latter on retrieve the information. b) You want to send the object to another application.

A reference is nothing more than a pointer to where the object is. So in either case you simply cannot access the memory because in a) it is reserved for your application and in b) it is another machine and it doesn't even exists.

http://en.csharp-online.net/Glossary:Definition_-_Reference_type

Sergio
+2  A: 

If you're using .NET 3 or later, you should use the DataContractSerializer and set PreserveObjectReferences to true.

HTH, Kent

Kent Boogaart
+1  A: 

your code example won't work simply because the XmlSerializer does not save reference information, during the serialization process it will simply write the data for obj to the stream twice this means that when you deserialize it will read the data for obj as two different instances, it has no way of knowing that they referred to the same instance at serialization time. using the DataContractSerializer mentioned before should give you what you want but note that it uses non standard xml (see: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx)

SpaceghostAli
Thank you for the link!
CodeChef