2014-05-21 56 views
0

我有一個遊戲數據類,看起來像這樣:屬性的派生類中被丟棄(即與基類的替代)在XML反序列化

public class SaveGameData { 

    public virtual List<PropertyContainer> properties {get; set; } 

} 

而且這些類太:

public class PropertyContainer { 

    public Property property {get; set; }//Could be set to DerivedProperty 

} 
public class Property { 
    public int BasePropertyData {get; set;} 
} 
public class DerivedProperty : Property { 
    public int DerivedPropertyData {get; set; }  
} 

我試圖在遊戲會話之間保存/加載這些數據,我正在爲這個過程使用XML序列化/反序列化。

的問題是,在PropertyContainer類中,派生屬性有時subistution用於物業類,像這樣:

PropertyContainer container = new PropertyContainer(); 
container.property = derivedProperty; 

當容器被序列化,派生類和它的特殊屬性也保存了,這裏沒問題。

這裏的序列化代碼:

serializer = new System.Xml.Serialization.XmlSerializer(typeof(SaveGameData)); 

SaveGameData dataToSave = GetSaveGameData(); 
using (var stream = new StringWriter()) { 
serializer.Serialize(stream, dataToSave); 
...write to file... 

} 

序列化過程似乎是工作,因爲派生類中得到了肯定,正確保存爲XML文件,XML輸出看起來是這樣的:

<?xml version="1.0" encoding="utf-16"?> 
<SaveGameData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

    <properties> 

    <PropertyContainer> 

     <property xsi:type="DerivedProperty"> 

     <BasePropertyData>1</BasePropertyData> 
     <DerivedPropertyData>1</DerivedPropertyData> 

     </property> 

    </PropertyContainer> 

    </properties> 

</SaveGameData> 

但是,當XML文件反序列化時,所有派生類都將被丟棄。這裏的反串行化代碼:

SaveGameData result; 
string data = ReadSaveGameData(); 
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SaveGameData)); 

     using (StringReader stream = new StringReader(savedGame)) { 
      result = (SaveGameData)serializer.Deserialize(stream); 

     } 

加載XML數據之後這意味着,在派生屬性調用GetType()(例如saveGameData.properties[0].GetType(),假設屬性是DerivedProperty)。將產生的基類,即Property;它通過擴展丟棄所有DerivedProperty的屬性。有問題。

P.S: 我嘗試添加XmlInclude屬性,但什麼都沒有改變:

[System.Xml.Serialization.XmlInclude(typeof(DerivedProperty))] 
public class Property { 

... 

} 

我該如何解決這個問題?我的方法有沒有可行的選擇?

回答

0

裝飾Property[XmlInclude(typeof(DerivedProperty))]應該有工作。的確,如果沒有它,XmlSerializer甚至不會讓你首先序列化一個DerivedProperty

以下程序是基於您的代碼的工作示例。請確認您的機器上的控制檯輸出也是True。如果是這樣,您需要確定代碼與原始嘗試的不同之處。然後更新您的問題,以便我們可以深入挖掘。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Xml.Serialization; 

class Program 
{ 
    static void Main() 
    { 
     string savedGame = @" 
<SaveGameData xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> 
    <properties> 
    <PropertyContainer> 
     <property xsi:type='DerivedProperty'> 
     <BasePropertyData>1</BasePropertyData> 
     <DerivedPropertyData>1</DerivedPropertyData> 
     </property> 
    </PropertyContainer> 
    </properties> 
</SaveGameData>"; 
     XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData)); 
     SaveGameData result; 

     using (StringReader stream = new StringReader(savedGame)) 
     { 
      result = (SaveGameData)serializer.Deserialize(stream); 
     } 

     Console.WriteLine(result.properties[0].property is DerivedProperty); // True 
    } 
} 

public class SaveGameData 
{ 
    public virtual List<PropertyContainer> properties { get; set; } 
} 

public class PropertyContainer 
{ 
    public Property property { get; set; }//Could be set to DerivedProperty 
} 

[XmlInclude(typeof(DerivedProperty))] 
public class Property 
{ 
    public int BasePropertyData { get; set; } 
} 

public class DerivedProperty : Property 
{ 
    public int DerivedPropertyData { get; set; } 
} 
+0

我不完全確定這個不存在的錯誤是如何通過我,但它肯定是地獄浪費了我的時間。謝謝你指出。 – Abdulaziz

0

一種選擇是切換到DataContractSerializer。然後使用KnownTypeAttribute來識別子類。

public class PropertyContainer { 

    public Property property {get; set; }//Could be set to DerivedProperty 

} 
[KnownType(typeof(DerivedProperty))] 
public class Property { 
    public int BasePropertyData {get; set;} 
} 
public class DerivedProperty : Property { 
    public int DerivedPropertyData {get; set; }  
}