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

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,递归构建XmlDocument或XDocument - 用第三方库如 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
- 将
ExpandoObject转为字典 - 用
XDocument逐层创建元素与属性(注意处理嵌套、数组、null 值) - 适用于配置导出、调试日志等非关键路径场景
这种方式绕过了 XmlSerializer 限制,但需自行保证 XML 合法性与结构清晰性。










