如何阻止C#9 positional record被XmlSerializer序列化?
阻止C# 9位置Record被XmlSerializer序列化的方案
一、完全禁用Xml序列化的几种方法
如果你想彻底让FiscalTag这个Record无法被XmlSerializer序列化,有以下几种可行方案:
1. 移除公共无参构造函数
XmlSerializer序列化对象的前提是目标类型拥有公共无参构造函数,如果这个无参构造不是必须的,直接删除即可:
public record FiscalTag(int Code, string Value, List<FiscalTag> ChildTags);
这样XmlSerializer会因找不到合法构造函数,无法对该类型执行序列化操作。
2. 实现IXmlSerializable接口并空实现
通过实现IXmlSerializable接口,但不提供任何实际的序列化逻辑,让XmlSerializer无法处理该类型:
public record FiscalTag(int Code, string Value, List<FiscalTag> ChildTags) : IXmlSerializable { public FiscalTag() : this(default, default, default) { } public XmlSchema GetSchema() => null; public void ReadXml(XmlReader reader) { } public void WriteXml(XmlWriter writer) { } }
3. 标记所有属性为XmlIgnore
给位置Record的每个参数添加[XmlIgnore]特性,让XmlSerializer忽略所有属性:
public record FiscalTag([XmlIgnore] int Code, [XmlIgnore] string Value, [XmlIgnore] List<FiscalTag> ChildTags) { public FiscalTag() : this(default, default, default) { } }
二、修正单元测试中的属性检测逻辑
针对你提到的单元测试中*EqualityContract*属性引发的误报问题,这里明确修正逻辑:*EqualityContract*是Record类型编译器自动生成的虚拟只读属性,它本身被标记了CompilerGeneratedAttribute(而普通自动属性的该特性仅标记在getter/setter上),因此可以通过判断属性本身是否带有该特性来排除它。
修正后的属性查询代码:
var autoProps = Type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic) .Where(property => property.CanRead && property.GetGetMethod(true).IsDefined(typeof(CompilerGeneratedAttribute), false) && !property.IsDefined(typeof(CompilerGeneratedAttribute))) .ToList();
这样就能过滤掉*EqualityContract*,避免因这个编译器生成的属性抛出不必要的异常。
内容的提问来源于stack exchange,提问作者bairog
相关产品推荐
相关产品推荐

