StackOverFlowException во время сериализации - PullRequest
1 голос
/ 11 февраля 2011

Я пытаюсь сериализовать пользовательский тип, который содержит словарь среди других членов. Типы, связанные с ключом и значением словаря, являются интерфейсами, которые реализованы.

Словарь выглядит как

 Dictionary<ITypeA, ITypeA> 

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

псевдокод выглядит примерно так:

            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;
            }

Я получаю StackOverflowException, когда вызывается WriteObject (), я не знаю, что вызывает это.

Все классы в иерархии декорированы с помощью [DataContract], а члены, подлежащие сериализации, обесценены с помощью [DataMember].

Любая помощь будет оценена.

1 Ответ

3 голосов
/ 11 февраля 2011

Я мог бы ожидать что-то подобное, если у вас есть цикл на графике, но который как-то не обнаружен как ошибка идентификации объекта.Под циклическим я подразумеваю:

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());
    }
}

, который выдает ошибку:

Граф объектов для типа 'Foo' содержит циклы и не может быть сериализован, если отслеживание ссылок отключено.

Это потому, что он пытается пройтись по дереву (не по графику), заметить повторение (идентичная ссылка на объект) и остановиться.Однако, протестировав вышесказанное (и увидев, когда вызывается get), похоже, что DCS действительно делает это, обнаруживая боль - глубина перед прерыванием очень велика.

Локально я получаю 528 звонков на Bar, прежде чем он умрет.Если у вас уже есть сложный код выше этого в стеке, он наверняка может объяснить переполнение стека.

...