我有简单的 C#9 位置记录,带有一个空构造函数(除了主构造函数之外):
public record FiscalTag(int Code, string Value, List<FiscalTag> ChildTags)
{
public FiscalTag() : this(default, default, default) { }
}
如何防止它被XmlSerializer序列化? 记录具有 EqualityContract (编译器生成的虚拟只读属性)。此属性会在我们的序列化单元测试中产生问题。所以我需要完全禁用序列化。
有关我们的单元测试问题的更多信息: 在我们的单元测试中,我们收集所有自动属性:
Type.GetProperties(BindingFlags.Instance |
BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic)
.Where(property => property.CanRead
&& property.GetGetMethod(true).IsDefined(typeof(CompilerGeneratedAttribute), false)
如果我们在该列表中找到任何只读 AutoProperty 或虚拟 AutoProperty - 我们会抛出异常(XmlSerializer 不支持它们)。
与普通 AutoProperties(其中 CompilerGenerateAttribute 属性应用于 getter 和 setter)不同,EqualityContract 属性本身应用了 CompilerGenerateAttribute 属性。此属性未序列化 - 因此可以安全地将其从我们的列表中排除:
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))
要故意破坏 xml 序列化,您可以实现
IXmlSerializable
:
public record FiscalTag(int Code, string Value, List<FiscalTag> ChildTags) : IXmlSerializable
{
public FiscalTag() : this(default, default!, default!) { }
const string NotSerializable = "suitable message here";
XmlSchema? IXmlSerializable.GetSchema() => throw new NotSupportedException(NotSerializable);
void IXmlSerializable.ReadXml(XmlReader reader) => throw new NotSupportedException(NotSerializable);
void IXmlSerializable.WriteXml(XmlWriter writer) => throw new NotSupportedException(NotSerializable);
}
这至少会在运行时给你一个合适的消息。