【问题标题】:DotNet XmlSerializer of Lists with constructor带有构造函数的列表的 DotNet XmlSerializer
【发布时间】:2013-04-03 15:20:40
【问题描述】:

我在 XmlSerializer 中发现了一些意外行为。 如果您对列表具有默认构造函数的对象列表进行脱轨,则该列表也会被附加。

有人知道如何解决这个问题吗? 这是一个例子。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace XmlSerialiserTest
{
    public class Schedule
    {
        public Schedule()
        {
            Days = new List<DayOfWeek>() { DayOfWeek.Monday };
            Time = DateTime.UtcNow;
        }
        public List<DayOfWeek> Days { get; set; }
        public DateTime Time { get; set; }
        public override string ToString()
        {
            return String.Format("{0},{1}", Time.ToShortTimeString(), string.Join(",", Days));
        }

    }

    public class Schedules
    {
        public List<Schedule> ScheduleList { get; set; }
        public Schedules()
        {
            ScheduleList = new List<Schedule>();
        }
        public override string ToString()
        {
            return string.Join(":",ScheduleList);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            // create a our list of Schedule with one schedule in
            // default constructor will give us Monday by default
            Schedules schedulesOut = new Schedules();
            schedulesOut.ScheduleList.Add(new Schedule());
            // Save
            XmlSerializer s = new XmlSerializer(typeof(Schedules));
            TextWriter writer = new StreamWriter("C:\\xmltest.xml");
            s.Serialize(writer,schedulesOut);
            writer.Close();
            Console.WriteLine(schedulesOut);
            // Output is 15:09,Monday
            // Now saved to disk and read back

            TextReader reader = new StreamReader("C:\\xmltest.xml");
            Schedules schedulesIn = (Schedules)s.Deserialize(reader);
            Console.WriteLine(schedulesIn);
            // Output is 15:09,Monday,Monday
            // schedulesIn in now contains two Mondays ,not one as expected

        }
    }
}

【问题讨论】:

    标签: .net deserialization xmlserializer


    【解决方案1】:

    这是预期的行为。为了能够“实例化”您的对象,它将始终调用无参数构造函数。实际上,为了能够反序列化,您总是需要一个无参数的构造函数。

    因为您的构造函数会创建列表并将Monday 添加为值,所以反序列化的对象将默认包含此值。

    虽然您确实可以使用数组,但我建议关注点分离并使用工厂方法手动创建Schedule 对象。然后工厂可以用星期一初始化第一个值。

    请注意,您确实需要公共无参数构造函数来进行反序列化。通常在使用工厂模式时,您会希望限制对构造函数的访问。

    【讨论】:

      【解决方案2】:

      将列表更改为数组。这按预期工作:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml.Serialization;
      using System.IO;
      
      namespace XmlSerialiserTest
      {
          public class Schedule
          {
              public Schedule()
              {
                 Days = new[] { DayOfWeek.Monday };
                 Time = DateTime.UtcNow;
              }
              public DayOfWeek[] Days { get; set; }
              public DateTime Time { get; set; }
              public override string ToString()
              {
                  return String.Format("{0},{1}", Time.ToShortTimeString(), string.Join(",",     Days));
          }
      
       }
      
      public class Schedules
      {
          public List<Schedule> ScheduleList { get; set; }
          public Schedules()
          {
              ScheduleList = new List<Schedule>();
          }
          public override string ToString()
          {
              return string.Join(":",ScheduleList);
          }
      }
      
      internal class Program
      {
          private static void Main(string[] args)
          {
              // create a our list of Schedule with one schedule in
              // default constructor will give us Monday by default
              Schedules schedulesOut = new Schedules();
              schedulesOut.ScheduleList.Add(new Schedule());
              // Save
              XmlSerializer s = new XmlSerializer(typeof (Schedules));
              TextWriter writer = new StreamWriter("C:\\xmltest.xml");
              s.Serialize(writer, schedulesOut);
              writer.Close();
              Console.WriteLine(schedulesOut);
              // Output is 15:09,Monday
              // Now saved to disk and read back
      
              TextReader reader = new StreamReader("C:\\xmltest.xml");
              Schedules schedulesIn = (Schedules) s.Deserialize(reader);
              Console.WriteLine(schedulesIn);
              // Output is 15:09,Monday,Monday
              // schedulesIn in now contains two Mondays ,not one as expected
      
          }
      }
      

      }

      【讨论】:

        猜你喜欢
        • 2011-11-27
        • 2020-07-13
        • 2014-10-12
        • 1970-01-01
        • 2013-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多