C#如何将匿名类型序列化为XML

17次阅读

xmlSerializer 不支持匿名类型,因其要求类型为 public 非 sealed、含公共无参构造函数和可读写属性,而匿名类型是 internal sealed、只读且无无参构造函数;推荐使用具名类替代。

C#如何将匿名类型序列化为XML

C# 中无法直接将匿名类型序列化为 XML,因为 XmlSerializer 要求类型必须有公共无参构造函数、公共可读写属性,且在编译时已知类型(即不能是匿名类型)。匿名类型是编译器生成的内部类,没有无参构造函数,也不支持 XML 序列化特性。

为什么 XmlSerializer 不支持匿名类型

XmlSerializer 在运行时通过反射生成临时程序集来实现序列化,它需要:

  • 类型必须是 public 且非 sealed(匿名类型是 internal sealed)
  • 所有序列化属性必须有 public get/set 访问器(匿名类型属性是只读的)
  • 类型必须有 public 无参构造函数(匿名类型没有)
  • 类型不能是泛型或匿名类型(明确被禁止)

可行的替代方案

若需输出类似匿名类型的 XML,推荐以下几种实用方式:

  • 使用预定义的具名类(最推荐):定义一个简单 public class,用属性对应所需字段,再用 XmlSerializer 序列化
  • 用 System.Text.json + XmlDocument(间接转 XML):先序列化为 json,再解析为 JsonDocument递归构建 XmlDocumentXDocument
  • 用第三方库如 ServiceStack.Text 或 DynamicXml:部分轻量库支持动态对象转 XML,但需引入额外依赖
  • 手动拼接 XML 字符串(仅限极简单场景):不推荐,易出错、无验证、难维护

示例:用具名类替代匿名类型

假设你原本写的是:

var data = new { Name = “Alice”, Age = 30 };

改为:

public class Person { public String Name { get; set; } = “”; public int Age { get; set; } }

var data = new Person { Name = “Alice”, Age = 30 };

var serializer = new XmlSerializer(typeof(Person));

using var writer = new StringWriter();

serializer.Serialize(writer, data);

string xml = writer.ToString(); // 正常输出格式化 XML

如果必须用动态数据结构

可借助 ExpandoObject(它是 IDictionary),配合自定义 XML 构建逻辑:

  • ExpandoObject 转为字典
  • XDocument 逐层创建元素与属性(注意处理嵌套、数组、NULL 值)
  • 适用于配置导出、调试日志等非关键路径场景

这种方式绕过了 XmlSerializer 限制,但需自行保证 XML 合法性与结构清晰性。

text=ZqhQzanResources