1

我在 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

        }
    }
}
4

2 回答 2

1

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

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

    }
}

}

于 2013-04-03T16:52:46.843 回答
1

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

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

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

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

于 2013-04-05T13:45:57.653 回答