我想序列化以下内容:
[Serializable]
[DefaultPropertyAttribute("Name")]
[XmlInclude(typeof(ItemInfo))]
[XmlInclude(typeof(ItemInfoA))]
[XmlInclude(typeof(ItemInfoB))]
public class ItemInfo
{
public string name;
[XmlArray("Items"), XmlArrayItem(typeof(ItemInfo))]
public ArrayList arr;
public ItemInfo parentItemInfo;
}
[Serializable]
[XmlInclude(typeof(ItemInfo))]
[XmlInclude(typeof(ItemInfoA))]
[XmlInclude(typeof(ItemInfoB))]
public class ItemInfoA : ItemInfo
{
...
}
[Serializable]
[XmlInclude(typeof(ItemInfo))]
[XmlInclude(typeof(ItemInfoA))]
[XmlInclude(typeof(ItemInfoB))]
public class ItemInfoB : ItemInfo
{
...
}
itemInfo
类描述了一个容器,它可以容纳数组列表中的其他itemInfo
对象,parentItemInfo
描述了哪个是父容器项目信息。
因为 ItemInfoA
和 ItemInfoB
派生自 ItemInfo
它们也可以是数组列表和 parentItemInfo
,因此当尝试序列化这些对象时(它可以在层次结构中包含许多对象)它失败并出现异常
IvvalidOperationException.`there was an error generating the xml file `
我的问题是:
添加 ItemInfo
类需要什么属性才能序列化?
注意:仅当使用parentItemInfo
或arrayList 初始化ItemInfo[A]/[B] 时才会出现异常。
请帮忙!
谢谢!
最佳答案
对于编辑过的问题,看起来你有一个循环。请注意,XmlSerializer
是一个树 序列化器,而不是一个图 序列化器,因此它会失败。这里通常的修复是禁用向上遍历:
[XmlIgnore]
public ItemInfo parentItemInfo;
请注意,当然,您必须在反序列化后手动修复父级。
关于异常 - 你需要查看 InnerException
- 它可能会准确地告诉你这一点,例如在你的 (catch ex)
中:
while(ex != null) {
Debug.WriteLine(ex.Message);
ex = ex.InnerException;
}
我猜它实际上是:
"A circular reference was detected while serializing an object of type ItemInfoA."
关于设计的更多一般,老实说,(公共(public)领域,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
{
}
根据要求,这里有一个一般的(不是特定于问题的)递归设置父级在 hive 中的说明(为了好玩,我在堆上使用深度优先;对于布雷斯优先,只需将 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);
}
}
}
}
关于C# xml serializer - 序列化派生对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4859935/