2011-10-26 68 views
9

我有一個類:如何使用帶XDocument的構造函數將XML反序列化爲對象?

public class MyClass 
{ 
    public MyClass(){} 
} 

我希望能夠直接在構造這樣的機器使用XMLSeralizer反序列化一個XDocument:

public class MyClass 
{ 
    private XmlSerializer _s = new XmlSerializer(typeof(MyClass)); 

    public MyClass(){} 
    public MyClass(XDocument xd) 
    { 
     this = (MyClass)_s.Deserialize(xd.CreateReader()); 
    } 
} 

除了不准我分配到「這「在構造函數內。

這可能嗎?

+0

對於要那樣做是什麼原因? – Fischermaen

+0

因爲實例化這個類並給它提供一個XDocument並讓它自己設置就好了。還有其他解決方案,但這對我來說似乎是最優雅的...我願意提供更好的建議。 –

+0

難道你不能設置類將數據序列化到它,從而爲你創建實例嗎? – Yatrix

回答

26

不,這是不可能的。序列化器在反序列化時創建對象。你已經創建了一個對象。相反,請提供一個靜態方法來從XDocument構造。

public static MyClass FromXml (XDocument xd) 
{ 
    XmlSerializer s = new XmlSerializer(typeof(MyClass)); 
    return (MyClass)s.Deserialize(xd.CreateReader()); 
} 
+0

以及如何在編譯時未知extraTypes(knownTypes)時應該如何使用冰箱?這很邪惡,在開始反序列化之前,我們甚至沒有預先回調init的東西? –

6

使用靜態負載方法更爲標準。

public class MyClass 
{ 
    public static MyClass Load(XDocument xDoc) 
    { 
     XmlSerializer _s = new XmlSerializer(typeof(MyClass)); 
     return (MyClass)_s.Deserialize(xDoc.CreateReader()); 
    } 
} 
3

更好使用某種工廠的,例如:

public static MyClass Create(XDocument xd) 
{ 
    XmlSerializer _s = new XmlSerializer(typeof(MyClass)); 
    return (MyClass)_s.Deserialize(xd.CreateReader()); 
} 
-1

簡單的回答你的問題是否定的,你不能。因此,原因是您在反序列化時創建了一個對象。

但是如果你真的堅持讓對象自己實例化自己的可能性,你可以使用一個私有的靜態實例變量,你可以使用反序列化後得到的對象加載它。那麼其他公共成員應在實例工作(當它不爲空即是)

一個例子(從我的頭,所以有輕微的機會,它是不完全正確):

public class MyClass 
{ 
    private XmlSerializer _s = new XmlSerializer(typeof(MyClass)); 
    private static MyClass mInstance = null; 

    public MyClass() { /* initialization logic */ } 
    public MyClass(XDocument xd) 
    { 
     mInstance = (MyClass)_s.Deserialize(xd.CreateReader()); 
    } 

    public void DoSomething() 
    { 
    if (mInstance != null) 
     mInstance.DoSomething(); 
    else 
    { 
     // logic for DoSomething 
    } 

    } 
} 

我希望這可以說明一點,但我不喜歡這樣的設計。我認爲這使得它過於複雜和錯誤敏感。

+0

您意識到您實例化的每個MyClass都會替換之前的靜態mInstance實例嗎?然後,所有實例化的MyClass對象將在內存中使用相同的對象。 – SamuelWarren

1

我想做同樣的事情,決定執行以下操作:

public class MyClass 
{ 
    public MyClass(){ 
    } 

    public MyClass(XDocument xd) 
    { 
     var t = typeof(MyClass); 
     var o = (MyClass)new XmlSerializer(t).Deserialize(xd.CreateReader()); 

     foreach (var property in t.GetProperties()) 
      property.SetValue(this, property.GetValue(o)); 
    } 
} 
相關問題