C#无法让我的字典在XML中序列化
我正在开发一个小项目来学习如何在C#.NET中序列化对象我创建了以下类,这是我尝试序列化的类:
public class Object { private Dictionary dictionaryStringInt; public Object() { this.dictionaryStringInt = new Dictionary(); } public void AddToDictionary(string s, int i) { this.dictionaryStringInt.Add(s, i); } public List DictionaryStringInt { get { List list = new List(); foreach (KeyValuePair element in dictionaryStringInt) { list.Add(new DictionaryEntry(element.Key, element.Value)); } return list; } set { Dictionary dictionary = new Dictionary(); foreach (DictionaryEntry entry in value) { dictionary.Add(entry.Key, entry.Value); } dictionaryStringInt = dictionary; } } public class DictionaryEntry { private string key; private int value; public DictionaryEntry() { this.key = string.Empty; this.value = 0; } public DictionaryEntry(string key, int value) { this.key = key; this.value = value; } [XmlAttribute("Key")] public string Key { get { return key; } set { key = value; } } [XmlText] public int Value { get { return value; } set { this.value = value; } } } }
我在这里有这个代码来完成工作:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { this.ClearTextBox(); SerialisationTest.Object @object = this.SetUpObject(); this.Serialize(@object); @object = null; @object = this.Deserialise(@"C:\Sources\SerialisationTest\test.xml"); this.textBox1.Text = @object.ToString(); this.DisplayXML(@object); } public void Serialize(SerialisationTest.Object @object) { XmlSerializer serializer = new XmlSerializer(typeof(SerialisationTest.Object)); using (TextWriter writer = new StreamWriter(@"C:\Sources\SerialisationTest\test.xml")) { serializer.Serialize(writer, @object); } } public SerialisationTest.Object Deserialise(string path) { XmlSerializer serializer = new XmlSerializer(typeof(SerialisationTest.Object)); using (TextReader reader = new StreamReader(path)) { return (SerialisationTest.Object)serializer.Deserialize(reader); } } public void DisplayXML(SerialisationTest.Object @object) { XmlSerializer serializer = new XmlSerializer(typeof(SerialisationTest.Object)); using (StringWriter writer = new StringWriter()) { serializer.Serialize(writer, @object); this.textBox1.Text = writer.ToString(); } } public SerialisationTest.Object SetUpObject() { SerialisationTest.Object @object = new SerialisationTest.Object(); @object.AddToDictionary("1", 1); @object.AddToDictionary("2", 2); @object.AddToDictionary("3", 3); return @object; } public void ClearTextBox() { this.textBox1.Text = ""; } }
现在这是我在文本框中看到的结果:
现在大多数代码都是我在试图序列化事物。 但后来我尝试序列化DictionaryStringInt
并在MSDN上看到Dictionary无法序列化。 因此,我尝试通过让属性返回DictionaryEntry
列表并将此列表转换为setter中的字典来欺骗序列化程序。 但正如您所看到的, DictionaryStringInt
的数据未被序列化。 我希望得到类似的东西:
1 2 3
有谁知道如何实现这一目标? (顺便说一句,我知道如果在反序列化字典时我在XML中有多个相同的键,我会得到某种类型的KeyAlreadyPresentException,这是一种行为需要)
谢谢!
编辑
我刚刚发现"C:\Sources\SerialisationTest\test.xml"
包含正确的结果。
因此,使用StringWriter进行反序列化或显示序列化似乎存在问题。
有什么我做错了吗?
EDIT2
简化了代码
EDIT3
我查看了评论中链接的答案,我认为我得到了正在发生的事情……在其中一个答案中有一条评论指出,不会调用setter,而是应该使用数组。 我在调查这个。
问题是在反序列化期间丢失了代理List
属性的内容。 解决方法是将其更改为数组:
DictionaryEntry [] DictionaryStringInt { get { if (dictionaryStringInt == null) return null; List list = new List (); foreach (KeyValuePair element in dictionaryStringInt) { list.Add(new DictionaryEntry(element.Key, element.Value)); } return list.ToArray(); } set { if (value == null) return; Dictionary dictionary = new Dictionary(); foreach (DictionaryEntry entry in value) { dictionary.Add(entry.Key, entry.Value); } dictionaryStringInt = dictionary; } }
有关在反序列化期间List
surrogate属性失败的原因的说明,请参阅使用XML反序列化器无法将XML反序列化为列表 。 如上所述:
-
XmlSerializer
调用getter来获取列表。 如果为null,则分配一个列表并通过setter设置它。 它在读取时保留在一些局部变量的列表中。 -
它反序列化每个列表元素,并将其添加到它所持有的列表中。
-
就是这样。 之后它永远不会调用包含类的list属性setter 。 因此,列表的内容永远不会填充到您的字典中。
-
但是,由于数组在分配后无法resize,因此必须在读取和反序列化其内容后对其进行分配和设置。 因此,在反序列化期间,数组属性可以充当代理。