我在班上得到了这个:
namespace MSAToolsLibrary.PublisherEntry
{
[XmlRoot(ElementName = "PublisherDatabase", Namespace = "http://www.publictalksoftware.co.uk/msa")]
public class PublisherData
{
public PublisherData()
{
//_Publishers = new List<Publisher>();
_PublishersDictionary = new Dictionary<string, Publisher>();
}
public List<Publisher> Publishers
{
get { return _PublishersDictionary.Select(x => x.Value).ToList(); }
set { _PublishersDictionary = value.ToDictionary(x => x.Name, x => x); }
}
private Dictionary<string, Publisher> _PublishersDictionary;
[XmlIgnore]
public Dictionary<string, Publisher> 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<DateTime>(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<Publisher>();
_PublishersDictionary = new Dictionary<string, Publisher>();
}
public List<Publisher> Publishers
{
get => _Publishers; set => _Publishers = value;
}
private List<Publisher> _Publishers;
然后这会导致数据正确序列化,并且我得到了MFC应用程序中的预期。但是现在我的PublisherDictionary
正悬而未决。所以我添加了一个函数:
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);
}
}
有效。但我不知道这是否是最简单的方法。我上面的问题是列表/字典现在彼此分离。因此,如果我将一个发布者添加到字典中,它现在将不在列表中。
目前,在读取XML后,如果我添加或删除发布者,我将其应用于列表和字典。除非有更简单的方法。
答案 0 :(得分:1)
序列化程序只会调用List的getter,然后为它找到的每个元素调用Add
,为它提供从该元素反序列化的类型的实例。
如果您的要求是同时拥有列表和字典,则必须提供类型的实现,并实现适用的接口。
以下ListDict使用List和Dictionary作为其后备存储,同时实现在(de)序列化中使用的IList。
public class ListDict<K, T>:IList<T>
{
public Dictionary<K, T> dict = new Dictionary<K, T>();
public List<T> list = new List<T>();
Func<T,K> KeyFunc;
// takes an Function that returns a key for T
public ListDict(Func<T,K> 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<T>
}
现在,您的PublisherData类将按如下方式更改以利用上述类:
[XmlRoot(ElementName = "PublisherDatabase", Namespace = "http://www.publictalksoftware.co.uk/msa")]
public class PublisherData
{
private ListDict<string, Publisher> _PublishersDictionary;
public PublisherData()
{
// provide the function to generate a key for a Publisher
_PublishersDictionary = new ListDict<string,Publisher>( (p) => p.Name );
}
[XmlElement]
public ListDict<string,Publisher> Publishers
{
get { return _PublishersDictionary; }
}
[XmlIgnore]
public Dictionary<string, Publisher> PublisherDictionary
{
get {return _PublishersDictionary.dict; }
}
}
使用上面的类在反序列化后直接给我一个填充列表和Dictionary。您必须确保在ListDict中保持后备存储同步。也许你可以没有它,但这取决于你的确切用例。