简体   繁体   English

如何使用带有XDocument的构造函数将XML反序列化为对象?

[英]How do I deserialize XML into an object using a constructor that takes an XDocument?

I have a class: 我有一节课:

public class MyClass
{
   public MyClass(){}
}

I would like to be able to use an XMLSeralizer to Deserialize an XDocument directly in the constructor thus: 我希望能够使用XMLSeralizer直接在构造函数中反序列化XDocument:

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

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

Except I am not allowed to assign to "this" within the constructor. 除了我不允许在构造函数中指定“this”。

Is this possible? 这可能吗?

No, it's not possible. 不,这是不可能的。 Serializers create objects when they deserialize. 序列化程序在反序列化时创建对象。 You've already created an object. 你已经创建了一个对象。 Instead, provide a static method to construct from an XDocument. 相反,提供一个静态方法来从XDocument构造。

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

It's more standard to use a static load method. 使用静态加载方法更为标准。

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

Is better use some kind of factory, eg: 最好使用某种工厂,例如:

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

I wanted to do the same thing and decided to do the following: 我想做同样的事情并决定做以下事情:

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));
   }
}

The simple answer to your question is no, you can't. 你的问题的简单答案是否定的,你不能。 Reason therefore is that you create an object when you deserialize. 因此,原因是您在反序列化时创建了一个对象。

But if you really insist on the possibility for an object to instantiate itself so-to-speak, you can use a private static instance variable which you can load with the object you get after deserialization. 但是如果你真的坚持对象实例化自己的可能性,你可以使用私有静态实例变量,你可以用反序列化后获得的对象加载它。 The other public members should then work on the instance ( when it's not null that is ) 然后其他公共成员应该在实例上工作(当它不是null时)

an example ( out of my head, so there is a slight chance it isn't entirely correct ) : 一个例子(从我的头脑中,所以有一点点可能不完全正确):

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
     }

  }
}

I hope this makes it a bit clear, but I'm not fond of such design. 我希望这有点清楚,但我不喜欢这样的设计。 I think it makes it all overly complex and error sensitive. 我认为这使得它过于复杂且对错误敏感。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM