2013-04-03 74 views
1

我在XmlSerializer中發現了一些意外的行爲。 如果將列表中具有默認構造函數的對象列表進行了刪除操作,那麼該列表也會被添加。列表的DotNet 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 

     } 
    } 
} 

回答

1

這是正常現象。爲了能夠「實例化」你的對象,它總是會調用無參數的構造函數。實際上,要能夠反序列化,您將始終需要一個無參數的構造函數。

因爲您的構造函數創建列表並將Monday作爲值添加,所以反序列化的對象將默認包含此值。

g雖然你的確可以使用數組,我會建議分離 - 關注和使用工廠方法手動創建Schedule對象。工廠可以在星期一初始化第一個值。

請注意,您確實需要用於反序列化的公共無參數構造函數。通常在使用工廠模式時,您想要限制對構造函數的訪問。

+0

很好的回答,歡呼聲 – Kaya

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 

    } 
} 

}

相關問題