Я получаю исключение, пытающееся сериализовать график объекта (не очень глубокий). Значимая часть его, как это:protobuf-net: обнаружена возможная рекурсия
[ОШИБКА] ФАТАЛЬНОЕ необработанное исключение: ProtoBuf.ProtoException: Возможная рекурсии д etected (смещение: 5 уровня (ов)): красный на ProtoBuf.ProtoWriter.CheckRecursionStackAndPush (объект) < 0x00127> в ProtoBuf.ProtoWriter.StartSubItem (объект, ProtoBuf.ProtoWriter, BOOL) < 0x0002f>
график представляет собой структуру файла/каталога и моя модель (упрощенно) выглядит следующим образом:
[ProtoContract]
[ProtoInclude(100, typeof(PackageDirectory))]
[ProtoInclude(200, typeof(PackageFile))]
public abstract class PackageMember
{
[ProtoMember(1)]
public virtual string Name { get; protected set; }
[ProtoMember(2, AsReference=true)]
public PackageDirectory ParentDirectory { get; protected set; }
}
[ProtoContract]
public class PackageDirectory : PackageMember
{
[ProtoMember(3)]
private Dictionary<string, PackageMember> _children;
public PackageDirectory()
{
_children = new Dictionary<string, PackageMember>();
}
public PackageDirectory (string name, PackageDirectory parentDirectory)
: this()
{
this.ParentDirectory = parentDirectory;
this.Name = name;
}
public void Add (PackageMember member)
{
_children.Add(member.Name, member);
}
}
[ProtoContract]
public class PackageFile : PackageMember
{
private Stream _file;
private BinaryReader _reader;
private PackageFile()
{}
public PackageFile (string name, int offset, int length, PackageDirectory directory, Stream file)
{
this.Name = name;
this.Length = length;
this.Offset = offset;
this.ParentDirectory = directory;
_file = file;
_reader = new BinaryReader(_file);
}
[OnDeserialized]
protected virtual void OnDeserialized(SerializationContext context)
{
var deserializationContext = context.Context as DeserializationContext;
if (deserializationContext != null)
{
_file = deserializationContext.FileStream;
_reader = new BinaryReader(_file);
}
}
[ProtoMember(3)]
public int Offset { get; private set; }
[ProtoMember(4)]
public int Length { get; private set; }
}
Глубина этого дерева составляет около 10-15 уровней, что меньше ProtoBuf.ProtoWriter.RecursionCheckDepth
значение (25). (Так что, может быть, это ошибка?) версия из Protobuf-нетто: одна составлена из ствола v2 (оборотов 491).
На самом деле, я решил его с модификацией кода protobuf-net. Я изменил значение ProtoBuf.ProtoWriter.RecursionCheckDepth
на 100, и все, кажется, в порядке.
Вопрос в том, есть ли какой-либо «истинный» способ сериализации такого графика без изменения кода protobuf? Является ли такое поведение правильным или это ошибка?
Моя платформа Mono-2.10-8 на Windows 7 Professional 64-битном
P.S. Также я обнаружил, что если я deserizlie с этим следующим кодом, у меня должен быть конструктор безпараметрического пакета PackageDirectory, который будет общедоступным.
var value = new PackageDirectory();
RuntimeTypeModel.Default.Deserialize(ms, value, typeof(PackageDirectory), new SerializationContext {
Context = new DeserializationContext {
FileStream = _file,
}});
Это еще одна тема, но она хорошо иллюстрируется представленным кодом. Я думаю, что в этом случае объявление частного конструктора должно быть разрешено, потому что теперь поведение отличается от одного для Serializer.Deserialize (...).
Проблема с конструктором звучит странно и неожиданно - опять же, потребуется повторить; на какой платформе это работает? регулярный .NET? или...?(SL и CF имеют некоторые незначительные различия здесь, из-за ограничений платформы) –
@MarcGravell, Извините за неполную информацию, я забыл указать свою платформу. Это моно. Я отредактирую вопрос. – ILya
моно на ...? Linux? IOS? Также: какой ** точный ** номер версии вы используете? –