2009-12-01 79 views
6

我有一個派生類,它只將方法添加到基類中。如何序列化派生類,以便它匹配基類的序列化? 即派生類的序列化的XML應該看起來像:如何序列化派生類作爲其基類

<BaseClass> 
    ... 
</BaseClass> 

例如 以下將引發InvalidOperationException 「不需要DerivedClass類型,請使用XmlInclude或SoapInclude屬性指定靜態未知的類型。」

Class BaseClass {} 

Class DerivedClass : BaseClass {} 

DerivedClass derived = new DerivedClass(); 

StreamWriter stream = new StreamWriter("output file path"); 
XmlSerializer serializer = new XmlSerializer(GetType(BaseClass)); 
serializer(stream, derived); 

回答

4

您必須將GetType(DerivedClass)傳遞給序列化器構造函數,它必須與您序列化的對象的類型相匹配。您可以使用<XmlRoot>屬性重命名爲根元素。這個示例代碼工作像預期一樣:

using System; 
using System.Xml.Serialization; 
using System.IO; 

class Program { 
    static void Main(string[] args) { 
    var obj = new DerivedClass(); 
    obj.Prop = 42; 
    var xs = new XmlSerializer(typeof(DerivedClass)); 
    var sw = new StringWriter(); 
    xs.Serialize(sw, obj); 
    Console.WriteLine(sw.ToString()); 

    var sr = new StringReader(sw.ToString()); 
    var obj2 = (BaseClass)xs.Deserialize(sr); 
    Console.ReadLine(); 
    } 
} 

public class BaseClass { 
    public int Prop { get; set; } 
} 
[XmlRoot("BaseClass")] 
public class DerivedClass : BaseClass { } 
+0

做的工作,謝謝。 – 2009-12-01 07:22:22

+0

夥計們,我在這裏遇到了同樣的問題,但這不起作用。我的基類是從XSD創建的,所以我不知道要在[XmlRoot]中放置什麼 is是類的名稱,或者是基類中根元素的名稱(我是否應該指定它的名稱空間,等等)? – Tejo 2011-12-20 14:15:22

+1

如果只知道基礎知識但不知道派生類型,是否有解決方案? – 2012-12-17 11:19:03

0

我還沒有嘗試過,但你能不能只投它?

serializer(stream, (BaseClass)derived); 

編輯

另外,如果你想有一個XmlSerialiser可與多個派生類&基類的應對,那麼你需要指定在XmlSerialiser構造的所有類型。

XmlSerializer serializer = new XmlSerializer(typeof(BaseClass), new Type[] {typeof(DerivedClass)}); 

然後它會愉快地序列化多種類型。但是,您還必須使用上述解決方案來獲取輸出xml以在類之間進行匹配。

+1

沒有相同的InvalidOperationException拋出 – 2009-12-01 05:17:18

0

谷歌搜索一點點後,)我可以說,你需要一些更多的代碼並執行IXmlSerializable爲你的基類,聲明所有接口方法爲虛擬化和壓倒一切的他們在你的派生類上。這裏有一個示例topicsimilar problem通過提到的接口解決。

1

您還可以實現對BaseClass的ICloneable接口,然後做:

var sw = new StringWriter() 

var base = (derived as BaseClass).Clone() 
var serializer = new XmlSerializer(typeof(BaseClass)) 
serializer.Serialize(sw, base) 

Console.WriteLine(sw.ToString()) 

不是一個完美的approche,但如果你的基類是簡單那麼它也應該工作。