情景:
Configuration
,Option
,Option1
和Option2
Option1
和Option2
继承自Option
Configuration
有一个List<Option>
类型的属性,我打算在其中存储从Option
下载的对象Option
是抽象的,永远不会用于构造实际的实例。问题:
[XmlType(...)]
和[XmlElement(...)]
属性注释这些对象和成员时,集合中对象的序列化最终会与我想要的不同[XmlArray(...)]
和[XmlArrayItem(...)]
属性,它看起来像我想要的那样,但是我必须在编译时指定一个已知的项类型列表,这样就无法实现可扩展性以下是您可以运行的示例LINQPad脚本:
void Main()
{
var Configuration = new Configuration();
Configuration.Options.Add(new Option1());
Configuration.Options.Add(new Option2());
var serializer = new XmlSerializer(typeof(Configuration), new Type[]
{
typeof(Option1),
typeof(Option2),
});
var ns = new XmlSerializerNamespaces();
ns.Add(string.Empty, string.Empty);
using (var writer = new StringWriter())
{
serializer.Serialize(writer, Configuration, ns);
writer.ToString().Dump();
}
}
[XmlType("configuration")]
public class Configuration
{
private readonly List<Option> _Options = new List<Option>();
[XmlElement("options")]
public List<Option> Options { get { return _Options; } }
[XmlArray("options2")]
[XmlArrayItem(typeof(Option1))]
[XmlArrayItem(typeof(Option2))]
public List<Option> Options2 { get { return _Options; } }
}
public class Option { }
[XmlType("option1")]
public class Option1 : Option { }
[XmlType("option2")]
public class Option2 : Option { }
运行此命令时,您将获得以下输出:
<?xml version="1.0" encoding="utf-16"?>
<configuration>
<options d2p1:type="option1" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
<options d2p1:type="option2" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
<options2>
<option1 />
<option2 />
</options2>
</configuration>
请注意第一个属性options
的序列化与options2
完全不同,但它们具有相同的内容。
基本上,我希望序列化的xml看起来像options2
,但不必通过属性指定允许的类类型,因为这将使扩展性变得不可能。
如果我必须通过可在运行时更改的内容提供它们,那很好,但在编译时硬编码是不行的。
答案 0 :(得分:2)
我认为您将不得不查看XmlAttributeOverrides
,它允许您在运行时提供属性。这不是琐碎的,但也不是精神融化。最大的问题:当你使用接受XmlAttributeOverrides
的构造函数时,每次都会生成 ,所以一定要缓存并重新使用XmlSerializer
实例 - 否则你会泄漏组件(它们无法收集)。
要实施,您需要调整XmlAttributes
和XmlArray
的{{1}}实例,然后使用XmlArrayItems
将其与XmlAttributeOverrides.Add(Type,Member,XmlAttributes)
相关联。