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

C#:如何通过XmlSerializer直接序列化列表生成指定派生类元素XML

直接序列化List<Bar>生成自定义元素名的XML方案

好问题!要实现直接序列化List<Bar>时生成和方法A一致的XML(也就是每个派生类对应<derived1>、<derived2>这类自定义元素名,而非带xsi:type的<base>),你可以通过动态配置XmlSerializer的属性重写来实现,不需要把列表包装到Test类里。下面是具体的实现思路和代码示例:

核心思路

XmlSerializer提供了带XmlAttributeOverrides参数的构造函数,允许我们在运行时覆盖默认的序列化规则——相当于给任意List<Bar>对象动态添加XmlArray和XmlArrayItem特性,和你在Test类成员上的配置效果完全一致。

完整代码示例

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

[XmlInclude(typeof(Foo1)), XmlInclude(typeof(Foo2))]
public abstract class Bar { public string s; }
public class Foo1 : Bar { }
public class Foo2 : Bar { }

class Program
{
    static void Main()
    {
        // 准备测试数据
        var barList = new List<Bar>
        {
            new Foo1 { s = "我是Foo1实例" },
            new Foo2 { s = "我是Foo2实例" },
            new Bar { s = "我是Bar基类实例" }
        };

        // 构建属性重写配置
        var overrides = new XmlAttributeOverrides();
        var xmlAttributes = new XmlAttributes();

        // 为每个派生/基类指定对应的XML元素名
        xmlAttributes.XmlArrayItems.Add(new XmlArrayItemAttribute("derived1", typeof(Foo1)));
        xmlAttributes.XmlArrayItems.Add(new XmlArrayItemAttribute("derived2", typeof(Foo2)));
        xmlAttributes.XmlArrayItems.Add(new XmlArrayItemAttribute("base", typeof(Bar)));

        // 设置根元素名为"Bars"(和Test类里的XmlArray属性一致)
        overrides.Add(typeof(List<Bar>), new XmlRootAttribute("Bars"));
        // 将配置应用到List<Bar>类型
        overrides.Add(typeof(List<Bar>), xmlAttributes);

        // 创建自定义XmlSerializer,必须传入XmlInclude的类型列表
        var serializer = new XmlSerializer(
            typeof(List<Bar>), 
            overrides, 
            new[] { typeof(Foo1), typeof(Foo2) }, 
            null, 
            null
        );

        // 执行序列化并输出结果
        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, barList);
            Console.WriteLine(writer.ToString());
        }
    }
}

关键细节说明

  • XmlAttributeOverrides的作用:它允许我们在运行时为目标类型(这里是List<Bar>)添加或修改序列化特性,完全替代了在类成员上标注XmlArrayItem的静态方式。
  • 根元素配置:通过XmlRootAttribute把默认的根元素名ArrayOfBar改成Bars,和Test类里的[XmlArray("Bars")]效果对齐。
  • XmlInclude的必要性:构造XmlSerializer时必须传入派生类类型,否则序列化过程中无法识别Foo1、Foo2,会抛出类型未被预期的异常。
  • 性能提示:每次创建带XmlAttributeOverrides的XmlSerializer都会生成动态程序集,建议对相同配置的序列化器进行缓存(比如用静态字典存储),避免频繁创建带来的性能损耗。

生成的XML效果

运行上述代码后,生成的XML会和方法A的输出完全一致:

<Bars>
  <derived1>
    <s>我是Foo1实例</s>
  </derived1>
  <derived2>
    <s>我是Foo2实例</s>
  </derived2>
  <base>
    <s>我是Bar基类实例</s>
  </base>
</Bars>

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:36:38