如何序列化/反序列化IList集合的类包装器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何序列化/反序列化IList集合的类包装器?相关的知识,希望对你有一定的参考价值。

我有基类Control,其中包含属性public ControlCollection Controls;

public abstract class Control { 
    ...
    public virtual string Name { get: set; }
    public ControlCollection Controls;
    public Control parent = null;
    ...
}

qazxsw poi是我自己的类,它实现了qazxsw poi:

ControlCollection

如果我将IList<Control>中的属性类型public sealed class ControlCollection : IList<Control>, IMySerializable { public int Count => _controls.Count; public bool IsReadOnly { get; } = false; public Control Parent; private List<Control> _controls = new List<Control>(); public ControlCollection(Control parent) { Parent = parent ?? throw new ArgumentNullException("parent"); } public Control this[int index] { get => _controls[index]; set => _controls[index] = value; } public void Add(Control child) { child.parent = Parent; _controls.Add(child); } ... } 更改为Controls,则下面的代码将形成正确的XML文件

ControlCollection

但如果一种属性List<Control>// temp data Control rootObj = new Button(); rootObj.Name = "111"; Control obj2 = new Label(); obj2.Name = "222"; Control obj3 = new Button(); obj3.Name = "333"; rootObj.Controls.Add(obj2); rootObj.Controls.Add(obj3); List<Type> list = new List<Type>(); rootObj.Controls.ForEach(child => child.DoActionWithChildren(node => { list.Add(node.GetType()); })); list.Add(typeof(Button)); list = list.Distinct().ToList(); // trying to set xml attributes. 'Controls' property will be a root of collection var attributes = new XmlAttributes(); list.ForEach(t => attributes.XmlArrayItems.Add(new XmlArrayItemAttribute(t))); var attrOverride = new XmlAttributeOverrides(); attrOverride.Add(typeof(Control), "Controls", attributes); // save data to file using(StreamWriter sw = new StreamWriter("path/to/xml/file.xml", false, Encoding.UTF8)) { XmlSerializer xs = new XmlSerializer(typeof(Control), attrOverride); XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add(string.Empty, string.Empty); xs.Serialize(sw, rootObj, ns); } /* ---------------------- */ output: <?xml version="1.0" encoding="utf-8"?> <Control d1p1:type="Button" xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance"> <Controls> <Control d1p1:type="Label"> <Controls /> <Name>22222</Name> </Control> <Control d1p1:type="Button"> <Controls /> <Name>32333</Name> </Control> </Controls> <Name>1111</Name> </Control> ,那么XML将被切断:

Controls

我试图改变类型:ControlCollection,但这不起作用。


我该怎么做才能正确序列化<?xml version="1.0" encoding="utf-8"?> <Button> <Controls> <Control d3p1:type="Label" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance"> <Controls /> ?然后,我应该知道如何正确地反序列化它?

答案

好吧,我修好了。事实证明,由于我的基类中的属性attrOverride.Add(typeof(ControlCollection), "Controls", attributes);,我有一个循环引用。我写了一个属性ControlCollection,它工作,即使与public Control parent = null;

我没有看到这个错误的原因是我的原始项目是一个Unity项目。 Unity没有向我展示这个错误。当我创建一个简单的C#控制台应用程序时 - 它向我显示了该错误。这很可悲但却是真实的。

以上是关于如何序列化/反序列化IList集合的类包装器?的主要内容,如果未能解决你的问题,请参考以下文章

WCF+Nhibernate循环引用导致序列化的问题

使用属性和未包装的集合反序列化 XML 响应

在使用Serde反序列化对象时,有没有办法省略包装器/根对象?

Phar反序列化漏洞原理

如何根据json中的属性编写jackson反序列化器

guid的值为null如何在C#反序列化