2017-08-04 37 views
0

我想获取从接口继承的对象列表并将它们序列化为xml(JSON也可接受)。这些对象中的每一个都从相同的抽象类继承,并且遵循相同的接口。如何序列化/反序列化从普通类继承的对象列表并遵循同一个接口?

请参见下面的类:

public abstract class Item 
{ 
    public string Name { get; set; } 
    public int SellIn { get; set; } 
    public int Quality { get; set; } 

    public Item(string name, int sellIn, int quality) 
    { 
     Name = name; 
     SellIn = sellIn; 
     Quality = quality; 
    } 

    public virtual void UpdateQuality() 
    { 
     //Default Behaviour 
    } 
} 

//子类

public class Appreciative : Item, IItem 
{ 
    public Appreciative(string name, int sellIn, int quality) : base(name, sellIn, quality) 
    {} 

    public override void UpdateQuality() 
    { 
     //Sub class behaviour 
    } 
} 

XmlSerializer类无法确定每个类的序列化/反序列化的时候,我明白了类型为什么,但我期待解决这个问题。

唯一的成功到目前为止我已经在使用它已成功序列化的数据如下ExtendedXmlSerializer:

<?xml version="1.0" encoding="utf-8"?> 
<ArrayOfIItem> 
<Depreciative type="CodingChallenge3.Internals.Items.Depreciative"> 
    <Name>+5 Dexterity Vest</Name> 
    <SellIn>9</SellIn> 
    <Quality>18</Quality> 
</Depreciative> 
<Appreciative type="CodingChallenge3.Internals.Items.Appreciative"> 
    <Name>Aged Brie</Name> 
    <SellIn>1</SellIn> 
    <Quality>1</Quality> 
</Appreciative> 
<Depreciative type="CodingChallenge3.Internals.Items.Depreciative"> 
    <Name>Elixir of the Mongoose</Name> 
    <SellIn>4</SellIn> 
    <Quality>5</Quality> 
</Depreciative> 
<Fixed type="CodingChallenge3.Internals.Items.Fixed"> 
    <Name>Sulfuras, Hand of Ragnaros</Name> 
    <SellIn>0</SellIn> 
    <Quality>80</Quality> 
</Fixed> 
<TicketEvent type="CodingChallenge3.Internals.Items.TicketEvent"> 
    <Name>Backstage passes to a TAFKAL80ETC concert</Name> 
    <SellIn>14</SellIn> 
    <Quality>20</Quality> 
</TicketEvent> 
<Depreciative type="CodingChallenge3.Internals.Items.Depreciative"> 
    <Name>Conjured Mana Cake</Name> 
    <SellIn>2</SellIn> 
    <Quality>4</Quality> 
</Depreciative> 
</ArrayOfIItem> 

的类型在type属性指定,但ExtendededXmlSerializer失败反序列化XML,说明空引用异常。

以下是读取和写入数据的存储库代码。

var serializedData = new ExtendedXmlSerializer().Serialize(inventory); 
     System.IO.File.WriteAllText(PATH, serializedData); 

var inventory = new List<IItem>(); 
     if (System.IO.File.Exists(PATH)) 
     { 
      var serializedData = System.IO.File.ReadAllText(PATH); 
      inventory = new ExtendedXmlSerializer().Deserialize<List<IItem>>(serializedData); 
     } 

我已阅读堆栈溢出的类似问题,但没有符合我的(到目前为止)。

编辑:堆栈跟踪

at ExtendedXmlSerialization.ExtendedXmlSerializer.ReadXml(XElement currentNode, TypeDefinition type, Object instance) 
at ExtendedXmlSerialization.ExtendedXmlSerializer.ReadXmlArray(XElement currentNode, TypeDefinition type, Object instance) 
at ExtendedXmlSerialization.ExtendedXmlSerializer.ReadXml(XElement currentNode, TypeDefinition type, Object instance) 
at ExtendedXmlSerialization.ExtendedXmlSerializer.Deserialize(String xml, Type type) 
at ExtendedXmlSerialization.ExtendedXmlSerializer.Deserialize[T](String xml) 
+0

嗯,我希望你不会不高兴;)......但有趣的是,这只是c&p或是你的抽象物品类没有实施IItem?你能添加异常的堆栈跟踪吗? – Fildor

+0

我改变了抽象类来实现IItem建议,但这并没有改变结果。现在添加堆栈跟踪 –

+0

如果您在创建序列化程序时包含相关类型(过载[像这样一个](https://msdn.microsoft.com/en-us/library/e5aakyae( v = vs.110).aspx)允许你指定序列化器应该处理的所有类型)。 –

回答

3

JSON也是可以接受的

我不太确定你想要什么,但你可以在Json.Net保存类型:

using Newtonsoft.Json; 

void Main() 
{ 
    var list = new List<IItem> { 
     new Appreciative("testing", 1, 2), 
     new Unappreciative("testing", 3, 4) 
    }; 

    var json = JsonConvert.SerializeObject(list, 
      new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }); 

    var newList = JsonConvert.DeserializeObject<List<IItem>>(json, 
      new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }); 

    foreach (var item in newList) { 
     Console.WriteLine(item.GetType().Name); 
     Console.WriteLine(item.Quality); 
     item.UpdateQuality(); 
     Console.WriteLine(item.Quality); 
    } 
} 

public interface IItem 
{ 
    string Name { get; set; } 
    int SellIn { get; set; } 
    int Quality { get; set; } 
    void UpdateQuality(); 
} 

public abstract class Item : IItem 
{ 
    public string Name { get; set; } 
    public int SellIn { get; set; } 
    public int Quality { get; set; } 

    public Item(string name, int sellIn, int quality) 
    { 
     Name = name; 
     SellIn = sellIn; 
     Quality = quality; 
    } 

    public virtual void UpdateQuality() 
    { 
     //Default Behaviour 
    } 
} 

//Sub classes 

public class Appreciative : Item 
{ 
    public Appreciative(string name, int sellIn, int quality) 
         : base(name, sellIn, quality) 
    {} 

    public override void UpdateQuality() 
    { 
     Quality = int.MaxValue; 
    } 
} 

public class Unappreciative : Item 
{ 
    public Unappreciative(string name, int sellIn, int quality) 
         : base(name, sellIn, quality) 
    {} 

    public override void UpdateQuality() 
    { 
     Quality = int.MinValue; 
    } 
} 

输出:

Appreciative 
2 
2147483647 
Unappreciative 
4 
-2147483648 
+0

嗯谢谢你,我会检查一下,看看现在用这个解决方案得到我需要的结果。 –

+0

这工作完美,我更喜欢JSON,再次感谢! –

相关问题