У меня есть сериализатор / десериализатор, который использует ссылки PreserveReferencesHandling = PreserveReferencesHandling.All
.
Проблема в том, что у меня есть циклические ссылки.
Вот очень простой пример.
class Node
{
public Node(object value)
{
Value = value;
}
public object Value { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
}
Мой тестовый сценарий:
var obj = new Node("o")
{
Left = new Node("oL"),
Right = new Node("oR")
};
obj.Right.Right = obj; // Circular reference!
При десериализации у меня появляется следующее IReferenceResolver
private class InternalReferenceResolver : IReferenceResolver
{
private readonly Deserializer _par;
public InternalReferenceResolver(Deserializer par)
{
_par = par;
}
public object ResolveReference(object context, string reference)
{
object refObject;
if (!_par._processed.TryGetValue(reference, out refObject))
{
refObject = _par.DeserializeObject(reference);
}
return refObject;
}
public string GetReference(object context, object value)
{
throw new NotSupportedException("Only for Serialization");
}
public bool IsReferenced(object context, object value)
{
return false;
}
public void AddReference(object context, string reference, object value)
{
_par._processed.Add(reference, value);
}
}
Как вы можете видеть, когда JSON.NET сообщает мненового ref-> объекта (через AddReference()
) я добавляю его в словарь.
Когда JSON.NET запрашивает объект для конкретной ссылки (через ResolveReference()
), я рекурсивную и десериализовываю эту ссылку.
Проблема заключается в том, что JSON.NET вызывает ResolveReference()
для каждой ссылки на объект, прежде чем он вызовет AddReference()
.
Я ожидаю, что поток десериализации будет:
- Определить тип объекта
- Построить объект
- AddReference (id, newObj)
- Разрешить ссылки + Заполнить свойства
Я вижу следующее:
- Определение типа объекта
- Разрешение ссылок
- Построениеobject
- AddReference (id, newObj)
- Заполнить свойства
Мои вопросы:
Почему это сделаново-вторых, я что-то упускаю с моим предложенным потоком?
как я могу преодолеть эту проблему, имея «голый» объект только для ссылок и только потом фактически разрешать ссылки?