Как десериализовать XML в объект с помощью конструктора, который принимает XDocument?

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

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 ответов


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

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

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

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

лучше использовать какой-то завод, например:

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

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

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

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

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

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

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
     }

  }
}

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