C# 抽象基类型到派生类型的C Xml序列化-哪个TypeName属性定义获胜?
我的设想: 我有一个我用属性定义的对象,这些属性用XmlElement标记修饰,并且有我定义的类型,其中一些类型是抽象类型,设置为各自的派生类型。我想使用XmlSerializer将整个对象序列化为XML,所有抽象属性都应该序列化为元素,并将TypeName设置为派生类型的TypeName 以下是对象的结构示例:C# 抽象基类型到派生类型的C Xml序列化-哪个TypeName属性定义获胜?,c#,xml-serialization,derived-class,abstract-base-class,C#,Xml Serialization,Derived Class,Abstract Base Class,我的设想: 我有一个我用属性定义的对象,这些属性用XmlElement标记修饰,并且有我定义的类型,其中一些类型是抽象类型,设置为各自的派生类型。我想使用XmlSerializer将整个对象序列化为XML,所有抽象属性都应该序列化为元素,并将TypeName设置为派生类型的TypeName 以下是对象的结构示例: [XmlType(TypeName = "MAINOBJECT")] public class MainObject { [XmlElement(Type = typeof(D
[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
[XmlElement(Type = typeof(DerivedClass))]
public BaseClass TheBase { get; set; }
}
[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
[XmlAttribute("AnAttribute")]
public string AnAttribute { get; set; }
[XmlElement("ANELEMENT")]
public string AnElement { get; set; }
}
[XmlType(TypeName = "DERIVEDCLASS")]
public class DerivedClass : BaseClass
{
[XmlElement("ANOTHERELEMENT")]
public string AnotherElement { get; set; }
}
但是,请注意,当我创建MainObject的新实例、填充它的属性并序列化它时,生成的XML是这样的:
<MAINOBJECT>
<BaseClass AnAttribute="">
<ANELEMENT/>
<ANOTHERELEMENT/>
</BaseClass>
</MAINOBJECT>
我想要的是:
<MAINOBJECT>
<DERIVEDCLASS AnAttribute="">
<ANELEMENT/>
<ANOTHERELEMENT/>
</DERIVEDCLASS>
</MAINOBJECT>
知道我做错了什么吗 也许不是最好的解决方案,但是:
class Program
{
static void Main(string[] args)
{
XmlAttributes attrs = new XmlAttributes();
XmlElementAttribute attr = new XmlElementAttribute();
attr.ElementName = "DerivedClass";
attr.Type = typeof(DerivedClass);
attrs.XmlElements.Add(attr);
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
attrOverrides.Add(typeof(MainObject), "TheBase", attrs);
XmlSerializer s = new XmlSerializer(typeof(MainObject), attrOverrides);
StringWriter writer = new StringWriter();
MainObject mo = new MainObject { TheBase = new DerivedClass { AnAttribute = "AnAttribute", AnElement = "AnElement", AnotherElement = "AotherElement" } };
s.Serialize(writer, mo);
Console.Write(writer.ToString());
}
}
将XmlElement名称添加到Main对象中的Base中,如下所示:
[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
[XmlElement("DERIVEDCLASS", Type = typeof(DerivedClass))]
public BaseClass TheBase { get; set; }
}
在我看来,这里最好的解决方案是实现接口,这样您就可以完全控制对象的序列化方式。当然,这需要更多的工作,但是如果您有这样的需求,而这些需求有点不同寻常,那么您也可能会遇到更多的怪癖,标准XmlSerializer在将来无法为您工作 这里有一个很好的教程:
另外,这里还有一些很好的信息:请理解,我不想硬编码元素的名称,我希望它动态选择从基类派生的任何类作为其类型名,我分配给基类。序列化不是这样工作的,因为如果有多个相同类型的属性,就无法区分它们。例如,public BaseClass TheBase和public BaseClass TheBase2。在这种情况下,第一个默认为base,第二个默认为base2,除非您指定了类型名。但是,我为要分配给基的派生类型指定了一个类型名。我希望它在序列化时使用派生类型的TypeName。我想的不对吗?是的,它类似于一个字符串属性,命名为string。例如,如果你有一个公共字符串TheBase,你希望序列化的名称是或吗?好吧,这很管用lol。我应该在一开始放弃它之前至少尝试一下,非常感谢:我的意思是[XmlElementDERIVEDCLASS,Type=typeofDerivedClass]公共基类TheBase{get;set;}我现在将研究使用IXmlSerializable,如果我能让我的实现正常工作,我将把它标记为正确答案。谢谢