2015-06-22 34 views
3

我試圖串行和deresial HistoryRoot類此XML格式:錯誤與XML反序列化一個IEnumerable類

<?xml version="1.0"?> 
<HistoryRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Files> 
    <HistoryItem d="2015-06-21T17:40:42" s="file:///D:\cars.txt" /> 
    </Files> 
    <Folders> 
    <HistoryItem d="2015-06-21T17:40:42" s="D:\fc\Cars" /> 
    </Folders> 
</HistoryRoot> 

下面是HistoryRoot,HistoryList和HistoryItem類:

[Serializable] 
public class HistoryRoot 
{ 
    public HistoryList 
    Files = new HistoryList 
    { 
     sl = new SortedList<DateTime, string>(), 
     list = new List<HistoryItem>(), 
     max = 500, 
     c = program.M.qFile 
    }, 
    Folders = new HistoryList 
    { 
     sl = new SortedList<DateTime, string>(), 
     list = new List<HistoryItem>(), 
     max = 100, 
     c = program.M.qFolder 
    }, 
} 

[Serializable] 
public class HistoryList : IEnumerable 
{ 
    [XmlIgnore] 
    public List<HistoryItem> list; 

    [XmlIgnore] 
    public SortedList<DateTime, string> sl; 

    [XmlIgnore] 
    public int max; 

    [XmlIgnore] 
    public ComboBox c; 

    public IEnumerator GetEnumerator() 
    { 
     if (list == null) list = new List<HistoryItem>(); 
     return list.GetEnumerator(); 
    } 
} 

public struct HistoryItem 
{ 
    [XmlAttribute("d")] 
    public DateTime D; 

    [XmlAttribute("s")] 
    public string S; 
} 

這是我得到的錯誤:

using (FileStream fs = new FileStream("filepath.xml", FileMode.Open)) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(HistoryRoot)); 
     HistoryRoot h = (HistoryRoot)serializer.Deserialize(fs); 
    } 

「有一個錯誤反射類型'History.HistoryRoot'。「 System.Exception {System.InvalidOperationException}
我該如何解決這個錯誤?謝謝!

回答

2

爲了序列化或反序列化類,使用XmlSerializer實現IEnumerable,類必須Add方法。從documentation

The XmlSerializer gives special treatment to classes that implement IEnumerable or ICollection. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method's parameter must be of the same type as is returned from the Current property on the value returned from GetEnumerator, or one of that type's bases.

你必須有這種方法,即使你從來沒有反序列化和只序列,因爲XmlSerializer不運行時代碼生成的序列化和反序列化在同一時間。

的方法實際上並不需要進行序列化工作成功,它只是需要現在

public void Add(object obj) 
    { 
     throw new NotImplementedException(); 
    } 

(當然,對於系列化成功,該方法)

+0

感謝你的幫助,我現在修好了:) – Sakura

1

儘管sbc的回答是正確的,我接受了它,但我現在更改HistoryList類,以使它更容易:

public class HistoryList : List<HistoryItem> // <-- Add List<HistoryItem> 
{  
    [XmlIgnore] 
    public SortedList<DateTime, string> sl; 

    [XmlIgnore] 
    public int max; 

    [XmlIgnore] 
    public ComboBox c; 
} 

然後改變HistoryRoot到:

[Serializable] 
public class HistoryRoot 
{ 
    public HistoryList 
    Files = new HistoryList 
    { 
     sl = new SortedList<DateTime, string>(), 
     //list = new List<HistoryItem>(), <-- Remove this line 
     max = 500, 
     c = program.M.qFile 
    }, 
    Folders = new HistoryList 
    { 
     sl = new SortedList<DateTime, string>(), 
     //list = new List<HistoryItem>(), <-- Remove this line 
     max = 100, 
     c = program.M.qFolder 
    }, 
}