我想创建一个通用抽象类型作为我的xml序列化类型的基础:
public abstract class RootElementBase<TEelment>
{
public IList<TElement> SubElements {get;set;}
public RootElementBase(){
SubElements = new List<T>();
}
}
我将这样使用:
[XmlRoot(ElementName = "myroot")]
public class MyRoot: RootElementBase<ItemType> {
[XmlElement("item")]
public override List<ItemType> Elements { get; set; }
}
但这不会序列化MyRoot类。实现的类型使用Elements类型的通用抽象类。但是将设置XmlElelemt属性标记。
答案 0 :(得分:0)
支持派生类型的序列化和反序列化。以下属性控制Xml序列化:
[XmlElement]
[XmlAttribute]
[XmlIgnore]
我们需要指示Xml序列化程序忽略我们希望在具体派生类型中使用的基类成员。
另外,在构造函数中要小心虚拟成员调用 见 - &gt; https://msdn.microsoft.com/en-us/library/ms182331.aspx
试一试:
使用派生类 MyRoot 作为 XmlSerializer 的类型参数
抽象基类:
[Serializable]
public abstract class RootElementBase<TEelment>
{
[XmlIgnore]
public virtual List<TEelment> SubElements { get; set; }
protected RootElementBase()
{
SubElements = new List<TEelment>();
}
}
具体类:
[XmlRoot(ElementName = "myroot")]
public class MyRoot : RootElementBase<ItemType>
{
[XmlElement("item")]
public override List<ItemType> SubElements { get; set; }
}
Dummy ItemType类:
public class ItemType
{
public string Name { get; set; }
}
这将输出以下内容:
<?xml version="1.0"?>
<myroot xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item>
<Name>Jim</Name>
</item>
<item>
<Name>Ben</Name>
</item>
<item>
<Name>Tom</Name>
</item>
</myroot>
测试控制台应用程序:
class Program
{
static void Main(string[] args)
{
MyRoot root = new MyRoot();
root.SubElements.Add(new ItemType() { Name = "Jim"});
root.SubElements.Add(new ItemType() { Name = "Ben" });
root.SubElements.Add(new ItemType() { Name = "Tom" });
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyRoot));
StringWriter stringWriter = new StringWriter();
xmlSerializer.Serialize(stringWriter, root);
Console.WriteLine(stringWriter);
Console.ReadKey();
}
}
使用抽象基类 RootElementBase 作为 XmlSerializer 的类型参数,并带有XmlRoot
覆盖参数
每个MSDN:
XML文档的根元素包含所有其他元素。 默认情况下,type参数指定的对象是序列化的 作为根元素。属性,例如XML元素名称 root元素取自type对象。但是,根 参数允许您替换默认对象的信息 指定XmlRootAttribute;该对象允许您设置 不同的命名空间,元素名称等。
https://msdn.microsoft.com/en-us/library/65k4wece(v=vs.110).aspx
抽象基类:
[Serializable]
[XmlInclude(typeof(MyRoot))]
public abstract class RootElementBase<TEelment>
{
[XmlIgnore]
public virtual List<TEelment> SubElements { get; set; }
protected RootElementBase()
{
SubElements = new List<TEelment>();
}
}
具体类:
[XmlRoot(ElementName = "myroot")]
public class MyRoot : RootElementBase<ItemType>
{
[XmlElement("item")]
public override List<ItemType> SubElements { get; set; }
}
Dummy ItemType类:
public class ItemType
{
public string Name { get; set; }
}
使用通用序列化的示例控制台应用
class Program
{
static void Main(string[] args)
{
MyRoot root = new MyRoot();
root.SubElements.Add(new ItemType() { Name = "Jim"});
root.SubElements.Add(new ItemType() { Name = "Ben" });
root.SubElements.Add(new ItemType() { Name = "Tom" });
string xml = Serialize(root, "myNewRoot");
Console.WriteLine(xml);
Console.ReadKey();
}
static string Serialize<TElement>(RootElementBase<TElement> tElement, string rootElementName)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(RootElementBase<TElement>),
new XmlRootAttribute(rootElementName));
StringWriter stringWriter = new StringWriter();
xmlSerializer.Serialize(stringWriter, tElement);
return stringWriter.ToString();
}
}
注意 - 使用此解决方案,您需要了解动态生成的程序集
动态生成的程序集 为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定的类型。基础结构查找并重用这些程序集。仅当使用以下构造函数时才会出现此问题:
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,并且永远不会卸载,这会导致内存泄漏和性能下降。最简单的解决方案是使用前面提到的两个构造函数之一。否则,您必须将程序集缓存在 Hashtable 中,如以下示例所示。
请参阅MSDN备注:https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer(v=vs.110).aspx