You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#序列化含两个不同类型列表的类时如何输出交替顺序的XML?

问题根因

你当前的写法给两个独立的List分别指定了Order=1和Order=2,XmlSerializer会优先序列化完所有Order值更小的元素,再序列化Order值更大的元素,所以才会出现所有<SLOW>节点在前、所有<FAST>节点在后的结果。


方案1:使用合并的多类型列表(推荐,无需自定义序列化逻辑)

不需要手动控制序列化全过程,仅调整类结构即可实现需求:

  1. 让Slow和Fast类继承同一个空基类(或实现同一个空接口),示例用基类SpeedItem举例:
public class SpeedItem
{
    // 空基类即可,无需额外属性
}

public class Slow : SpeedItem
{
    // 保留你的Slow类原有逻辑
}

public class Fast : SpeedItem
{
    // 保留你的Fast类原有逻辑
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:42:01