2011-10-26 36 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)); 
    } 
} 
相关问题