Jes*_*seF 7 .net c# polymorphism xmlserializer
我有一个对象,我正在尝试序列化为XML.在此对象内部是泛型类型(抽象类)的列表.此列表中的每个项可以是不同的类,但所有项都继承自抽象基类:
public abstract class animal
{
public string type { get; set; }
}
public class cat:animal
{
public string size { get; set; }
public string furColor { get; set; }
}
public class fish:animal
{
public string size { get; set; }
public string scaleColor { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我序列化列表时,我希望它看起来像这样:
<animal type="cat">
<size>medium</size>
<furColor>black</furColor>
</animal>
<animal type="fish">
<size>small</size>
<scaleColor>silver</scaleColor>
</animal>
Run Code Online (Sandbox Code Playgroud)
我尝试过简单的解决方案:
[XmlElement("Animal")]
public List<animal> Animals { get; set; }
Run Code Online (Sandbox Code Playgroud)
但它会引发错误,因为它不期望对象类型为"cat".将[XmlInclude]标记添加到基类,派生类或整个包含类(让我们称之为动物园)对此没有帮助.
我可以将typeof指定用于单个类:
[XmlElement("Animal", typeof(cat))]
public List<animal> Animals { get; set; }
Run Code Online (Sandbox Code Playgroud)
只要我只使用猫,这就可以正常使用.再一次,我在混合物中添加一条鱼,它会以相同的错误(不期待鱼)爆炸.
我可以添加多个typeof属性:
[XmlElement("Animal")]
[XmlElementAttribute(typeof(cat))]
[XmlElementAttribute(typeof(fish))]
public List<animal> Animals { get; set; }
Run Code Online (Sandbox Code Playgroud)
和这个编译,但忽略了元素名称,序列化对象作为<cat> </cat>和<fish> </fish>,分别,这是不可接受的.
我甚至尝试添加多个[XmlElement]标签:
[XmlElement("Animal", typeof(cat))]
[XmlElement("Animal", typeof(fish))]
public List<animal> Animals { get; set; }
Run Code Online (Sandbox Code Playgroud)
这个引发了一个不同的例外,这次对象"cat"和"fish"都在同一范围内使用"Animal"类型.
谁能想到解决这个问题的方法呢?
更新经过多一点挖掘后,我发现这个SO帖子建议将命名空间添加到基类:
[XmlRoot(Namespace="myNamespace")]
[XmlInclude(typeof(cat))]
[XmlInclude(typeof(fish))]
public abstract class animal
Run Code Online (Sandbox Code Playgroud)
序列化产生以下结果:
<animal xsi:type="cat" type="cat">
...
</animal>
<animal xsi:type="fish" type="fish">
...
</animal>
Run Code Online (Sandbox Code Playgroud)
其中xsi:type ="cat"指的是类的名称,type ="cat"指的是在基类中创建的type属性(参见最顶层的示例).这非常接近我所需要的,我担心我可能只是在这里缺乏经验,但有没有办法摆脱xsi:type属性列表?
将 XmlInclude 属性添加到基类应该可以解决此序列化问题
[Serializable]
[XmlInclude(typeof(cat))]
[XmlInclude(typeof(fish))]
class animals
{
....
}
public class cat:animals
{
public string size { get; set; }
public string furColor { get; set; }
}
public class fish:animals
{
public string size { get; set; }
public string scaleColor { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
更新
这是一个适合我的简单示例,我认为您实际上不需要 type 属性,因为您可以使用 typeof() 方法检索它。除非 type 属性有其他目的。
List<animal> animals = new List<animal>();
cat catofdoom = new cat();
catofdoom.furColor = "brown";
catofdoom.size = "10 pounds";
animals.Add(catofdoom);
fish fishofdoom = new fish();
fishofdoom.scaleColor = "blue";
fishofdoom.size = "12 inches";
animals.Add(fishofdoom);
try
{
XmlSerializer xs = new XmlSerializer(typeof(List<animal>));
using (StreamWriter wr = new StreamWriter("animal.xml"))
{
xs.Serialize(wr, animals);
}
}
catch (Exception e)
{
throw;
}
Run Code Online (Sandbox Code Playgroud)
结果如下(非常基本的序列化,没有选项):
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfAnimal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<animal xsi:type="cat">
<size>10 pounds</size>
<furColor>brown</furColor>
</animal>
<animal xsi:type="fish">
<size>12 inches</size>
<scaleColor>blue</scaleColor>
</animal>
</ArrayOfAnimal>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4693 次 |
| 最近记录: |