Как десериализовать XML в объект, используя конструктор, который принимает XDocument? - PullRequest
10 голосов
/ 26 октября 2011

У меня есть класс:

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

За исключением того, что я не являюсьразрешено присваивать «этому» в конструкторе.

Возможно ли это?

Ответы [ 5 ]

28 голосов
/ 26 октября 2011

Нет, это невозможно.Сериализаторы создают объекты при десериализации.Вы уже создали объект.Вместо этого предоставьте статический метод для конструирования из XDocument.

public static MyClass FromXml (XDocument xd)
{
   XmlSerializer s = new XmlSerializer(typeof(MyClass));
   return (MyClass)s.Deserialize(xd.CreateReader());
}
6 голосов
/ 26 октября 2011

Более стандартно использовать метод статической нагрузки.

public class MyClass
{
    public static MyClass Load(XDocument xDoc)
    {
        XmlSerializer _s = new XmlSerializer(typeof(MyClass));
        return (MyClass)_s.Deserialize(xDoc.CreateReader());
    }
}
4 голосов
/ 26 октября 2011

Лучше использовать какую-то фабрику, например ::1001*

public static MyClass Create(XDocument xd)
{
    XmlSerializer _s = new XmlSerializer(typeof(MyClass));
    return (MyClass)_s.Deserialize(xd.CreateReader());
}
1 голос
/ 22 июня 2016

Я хотел сделать то же самое и решил сделать следующее:

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));
   }
}
0 голосов
/ 28 октября 2011

Простой ответ на ваш вопрос - нет, вы не можете.Поэтому причина в том, что вы создаете объект при десериализации.

Но если вы действительно настаиваете на том, что объект может создавать свои собственные экземпляры, вы можете использовать приватную статическую переменную экземпляра, которую вы можете загрузить с объектом, полученным после десериализации.Затем другие открытые члены должны работать над экземпляром (если он не равен нулю)

примером (из моей головы, так что есть небольшая вероятность, что это не совсем правильно):

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
     }

  }
}

Надеюсь, это проясняет ситуацию, но мне не нравится такой дизайн.Я думаю, что это делает все это слишком сложным и чувствительным к ошибкам.

...