С отредактированным вопросом, похоже, у вас есть цикл.Обратите внимание, что XmlSerializer
- это сериализатор tree , а не сериализатор graph , поэтому произойдет сбой.Обычное исправление здесь - отключение обхода вверх:
[XmlIgnore]
public ItemInfo parentItemInfo;
Обратите внимание, что вам, конечно, придется вручную исправить родителей после десериализации.
В отношении исключения - вам нужно посмотреть наInnerException
- это, вероятно, говорит вам именно это, например, в вашей (catch ex)
:
while(ex != null) {
Debug.WriteLine(ex.Message);
ex = ex.InnerException;
}
Я предполагаю, что это действительно:
"Циркулярная ссылка былаобнаружен при сериализации объекта типа ItemInfoA. "
Больше обычно в дизайне, честно говоря, что (открытые поля, ArrayList
, настраиваемые списки) - плохая практика;вот более типичная перезапись , которая ведет себя одинаково :
[DefaultPropertyAttribute("Name")]
[XmlInclude(typeof(ItemInfoA))]
[XmlInclude(typeof(ItemInfoB))]
public class ItemInfo
{
[XmlElement("name")]
public string Name { get; set; }
private readonly List<ItemInfo> items = new List<ItemInfo>();
public List<ItemInfo> Items { get { return items; } }
[XmlIgnore]
public ItemInfo ParentItemInfo { get; set; }
}
public class ItemInfoA : ItemInfo
{
}
public class ItemInfoB : ItemInfo
{
}
в соответствии с просьбой, вот общая (не специфичная для вопроса) иллюстрация рекурсивной постановки родителей в улье(для ударов я использую первый в глубине кучи; для первого - просто поменяйте Stack<T>
на Queue<T>
; я стараюсь избегать рекурсии на основе стека в этих сценариях):
public static void SetParentsRecursive(Item parent)
{
List<Item> done = new List<Item>();
Stack<Item> pending = new Stack<Item>();
pending.Push(parent);
while(pending.Count > 0)
{
parent = pending.Pop();
foreach(var child in parent.Items)
{
if(!done.Contains(child))
{
child.Parent = parent;
done.Add(child);
pending.Push(child);
}
}
}
}