无法使用XmlSerializer读取XML内容

我在课堂上得到了这个:

namespace MSAToolsLibrary.PublisherEntry { [XmlRoot(ElementName = "PublisherDatabase", Namespace = "http://www.publictalksoftware.co.uk/msa")] public class PublisherData { public PublisherData() { //_Publishers = new List(); _PublishersDictionary = new Dictionary(); } public List Publishers { get { return _PublishersDictionary.Select(x => x.Value).ToList(); } set { _PublishersDictionary = value.ToDictionary(x => x.Name, x => x); } } private Dictionary _PublishersDictionary; [XmlIgnore] public Dictionary PublisherDictionary { get { return _PublishersDictionary; } } public void AddPublisher(String strName, String strNotes, Gender eGender, Appointed eAppointedAs, Serving eServingAs, bool bUseForDemonstrations, bool bAvailableMidweek, bool bAvailableWeekend, DateTime[] listDatesNotAvailable) { Publisher _Publisher = new Publisher() { Name = strName, Notes = strNotes, Gender = eGender, AppointedAs = eAppointedAs, ServingAs = eServingAs, }; _Publisher.Assignments.UseForDemonstrations = bUseForDemonstrations; _Publisher.Availability.Midweek = bAvailableMidweek; _Publisher.Availability.Weekend = bAvailableWeekend; _Publisher.Availability.DatesNotAvailable = new List(listDatesNotAvailable); //_Publishers.Add(_Publisher); _PublishersDictionary.Add(strName, _Publisher); } } } 

现在,当我将数据保存到XML时,一切正常。

但是当我读到时:

 public void ReadPublisherData(out Int64 iResult) { _PublisherData.Publishers.Clear(); // Reset iResult = MakeResult(true); try { XmlSerializer x = new XmlSerializer(_PublisherData.GetType()); using (StreamReader reader = new StreamReader(_strPathXML)) { _PublisherData = (PublisherData)x.Deserialize(reader); iResult = _PublisherData.PublisherDictionary.Count; } } catch { iResult = MakeResult(false); } } 

不起作用。 我在列表或字典中没有发布者。

我究竟做错了什么?

更新

如果我更改PublisherData声明,使其具有所需的后退字段:

 public PublisherData() { _Publishers = new List(); _PublishersDictionary = new Dictionary(); } public List Publishers { get => _Publishers; set => _Publishers = value; } private List _Publishers; 

然后这会导致数据正确序列化,我得到了MFC应用程序的预期。 但是现在我的PublisherDictionary正在悬挂。 所以我添加了一个function:

  public void BuildPublisherDictionary() { _PublishersDictionary = _Publishers.ToDictionary(x => x.Name, x => x); } 

并调整了读取例程:

  public void ReadPublisherData(out Int64 iResult) { iResult = MakeResult(true); try { _PublisherData.Publishers.Clear(); // Reset XmlSerializer x = new XmlSerializer(_PublisherData.GetType()); using (StreamReader reader = new StreamReader(_strPathXML)) { _PublisherData = (PublisherData)x.Deserialize(reader); _PublisherData.BuildPublisherDictionary(); iResult = _PublisherData.PublisherDictionary.Count; } } catch { iResult = MakeResult(false); } } 

有用。 但我不知道这是否是最简单的方法。 我上面的问题是列表/字典现在彼此分离。 因此,如果我将一个发布者添加到字典中,它现在将不在列表中。

更新2

目前,在读取XML后,如果我添加或删除发布者,我将其应用于列表和字典。 除非有更简单的方法。

序列化程序只调用List的getter,然后为它找到的每个元素调用Add ,为它提供从该元素反序列化的类型的实例。

如果您的要求是同时拥有列表和字典,则必须提供执行此类型的实现并实现适用的接口。

以下ListDict使用List和Dictionary作为其后备存储,同时实现在(de)序列化中使用的IList。

 public class ListDict:IList { public Dictionary dict = new Dictionary(); public List list = new List(); Func KeyFunc; // takes an Function that returns a key for T public ListDict(Func keyfunc) { KeyFunc = keyfunc; } // called by the serializer public void Add(T value) { Add( KeyFunc(value), value); } // fill both List and Dictionary public void Add(K key, T value) { list.Add(value); dict.Add( key , value); } // left out other required methods from IList } 

现在,您的PublisherData类将更改如下以利用上面的类:

 [XmlRoot(ElementName = "PublisherDatabase", Namespace = "http://www.publictalksoftware.co.uk/msa")] public class PublisherData { private ListDict _PublishersDictionary; public PublisherData() { // provide the function to generate a key for a Publisher _PublishersDictionary = new ListDict( (p) => p.Name ); } [XmlElement] public ListDict Publishers { get { return _PublishersDictionary; } } [XmlIgnore] public Dictionary PublisherDictionary { get {return _PublishersDictionary.dict; } } } 

使用上面的类在反序列化后直接给我一个填充列表和Dictionary。 您必须确保在ListDict中保持后备存储同步。 也许你可以没有它,但这取决于你的确切用例。