C#序列化含两个不同类型列表的类时如何输出交替顺序的XML?
问题根因
你当前的写法给两个独立的List分别指定了Order=1和Order=2,XmlSerializer会优先序列化完所有Order值更小的元素,再序列化Order值更大的元素,所以才会出现所有<SLOW>节点在前、所有<FAST>节点在后的结果。
方案1:使用合并的多类型列表(推荐,无需自定义序列化逻辑)
不需要手动控制序列化全过程,仅调整类结构即可实现需求:
- 让
Slow和Fast类继承同一个空基类(或实现同一个空接口),示例用基类SpeedItem举例:
public class SpeedItem { // 空基类即可,无需额外属性 } public class Slow : SpeedItem { // 保留你的Slow类原有逻辑 } public class Fast : SpeedItem { // 保留你的Fast类原有逻辑 }
- 修改
Type类,新增合并列表用于序列化,原有两个列表标记为不参与序列化,自动维护合并列表的交替顺序:
public class Type { private List<Slow> slowField; private List<Fast> fastField; // 原有列表标记为XmlIgnore,不参与序列化 [XmlIgnore] public List<Slow> SLOW { get => slowField; set { slowField = value; RefreshMergedList(); } } [XmlIgnore] public List<Fast> FAST { get => fastField; set { fastField = value; RefreshMergedList(); } } // 新增合并列表,指定不同类型对应的节点名 [XmlElement("SLOW", typeof(Slow))] [XmlElement("FAST", typeof(Fast))] public List<SpeedItem> MergedItems { get; set; } = new List<SpeedItem>(); // 按交替顺序刷新合并列表,可根据实际需求调整排序逻辑 private void RefreshMergedList() { MergedItems.Clear(); int maxCount = Math.Max(slowField?.Count ?? 0, fastField?.Count ?? 0); for (int i = 0; i < maxCount; i++) { if (i < slowField?.Count) MergedItems.Add(slowField[i]); if (i < fastField?.Count) MergedItems.Add(fastField[i]); } } }
序列化时XmlSerializer会严格按照MergedItems的元素顺序输出节点,Slow类型输出<SLOW>,Fast类型输出<FAST>,完全符合预期的交替效果。
方案2:实现IXmlSerializable接口自定义序列化逻辑
如果不想修改原有类的继承结构,可以自己实现序列化逻辑,完全保留原有公开属性结构:
public class Type : IXmlSerializable { public List<Slow> SLOW { get; set; } = new List<Slow>(); public List<Fast> FAST { get; set; } = new List<Fast>(); public XmlSchema GetSchema() => null; public void ReadXml(XmlReader reader) { // 反序列化逻辑,按节点名拆分到两个列表 reader.ReadStartElement(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.Name == "SLOW") { var slow = (Slow)new XmlSerializer(typeof(Slow)).Deserialize(reader); SLOW.Add(slow); } else if (reader.Name == "FAST") { var fast = (Fast)new XmlSerializer(typeof(Fast)).Deserialize(reader); FAST.Add(fast); } else { reader.Read(); } } reader.ReadEndElement(); } public void WriteXml(XmlWriter writer) { // 序列化逻辑,按交替顺序输出节点 int maxCount = Math.Max(SLOW.Count, FAST.Count); var ns = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); for (int i = 0; i < maxCount; i++) { if (i < SLOW.Count) { new XmlSerializer(typeof(Slow)).Serialize(writer, SLOW[i], ns); } if (i < FAST.Count) { new XmlSerializer(typeof(Fast)).Serialize(writer, FAST[i], ns); } } } }
内容的提问来源于stack exchange,提问作者Ankur Gupta
相关产品推荐
相关产品推荐

