3

I trying to serialize a custom type which holds a dictionary among other members. The types associated with key and value of the dictionary are interfaces which are implemented.

The dictionary looks like

 Dictionary<ITypeA, ITypeA> 

TypeA implements ITypeA, 
SubTypeOfA inherits from TypeA
SubTypeOfB inherits from SubTypeOfA

pseudo code looks something like this:

            List<Type> knownTypes = new List<Type>() { 
                typeof(TypeA), 
                typeof(SubTypeOfA),
                typeof(SubTypeOfB)
            };

DataContractSerializer serializer =
                new DataContractSerializer(typeof(DataHolder), knownTypes);

            using (FileStream fs = new FileStream(completeFilePath, FileMode.Create))
            {
                serializer.WriteObject(fs, templateData);
                success = true;
            }

I get a StackOverflowException when WriteObject() is getting called, am clueless on what is causing that to happen.

All the classes in the hierarchy are decorated with [DataContract] and the members to be serialized are decoreated with [DataMember].

Any help would be appreciated.

4
  • Do you get this exception the first time its called? Commented Feb 11, 2011 at 13:33
  • What is DataHolder? What is templateData? And what do the other types consist of, other than their inheritance? Commented Feb 11, 2011 at 13:36
  • Also, what is the message of the StackOverflowException? Does it give you any clues as to what went wrong? Commented Feb 11, 2011 at 13:42
  • 1
    The exception is thrown everytime. TemplateData is a custom type which has the data to be to serialized, it contains a dictionary among other objects. The message itself doesnt say anything useful, and you cant even get a stack trace for StackOverflowException, as the system is not in a stable state at that point. Commented Feb 15, 2011 at 17:31

1 Answer 1

4

I might expect something like this if you have a cycle in the graph, but which is somehow not detected as an object identity failure. By cyclic, I mean:

using System.Runtime.Serialization;
[DataContract] class Foo {
    public Foo() { Bar = this; }
    [DataMember] public Foo Bar { get; set; }
    static void Main() {
        new DataContractSerializer(typeof(Foo)).WriteObject(
            System.IO.Stream.Null, new Foo());
    }
}

which throws the error:

Object graph for type 'Foo' contains cycles and cannot be serialized if reference tracking is disabled.

This is because it is trying to walk the tree (not a graph), and noticing a repeat (identical object reference), and stopping. However, by testing the above (and seeing when the get is called), it looks like DCS actually does this by spotting pain - the depth before it aborts is very high.

Locally, I get 528 calls to Bar before it dies. If you already have complex code above this in the stack, it could account for a stack overflow, for sure.

Sign up to request clarification or add additional context in comments.

2 Comments

(for comparison, in my own serializer I start checking for cycles after about depth 10? 50? Something like that)
Marc - You were bang on target. One of the properties in the class was calling a constructor, which caused this whole recursive loop, causing the exception. Thanks a lot for the help..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.