TOC
集合
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var f = new XmlSerializer(typeof(TestClass));
using (var sw = new StringWriter())
{
f.Serialize(sw, new TestClass());
using (var sr = new StringReader(sw.ToString()))
{
var bt = (TestClass) f.Deserialize(sr);
Console.WriteLine(bt.ListIdentical());
}
}
}
}
public class TestClass
{
private List<int> PrivateList;
public List<int> MyList;
public bool ListIdentical()
{
return PrivateList == MyList;
}
public TestClass()
{
PrivateList = new List<int>() { 123, 567 };
MyList = PrivateList;
}
}
}
运行结果为 `True` 。实际上,如果把 `MyList` 换成只读属性,只要其值非 null / Nothing,则程序仍可以正常运行。
也就是说,反序列化过程复用了已有的集合实例。
发生变化的类
using System;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var f = new XmlSerializer(typeof(TestClass));
var f1 = new XmlSerializer(typeof(TestClass1));
using (var sw = new StringWriter())
{
f.Serialize(sw, new TestClass());
using (var sr = new StringReader(sw.ToString()))
{
var tc1 = (TestClass1) f1.Deserialize(sr);
Console.WriteLine("{0}, {1}", tc1.Value1, tc1.Value2);
}
}
}
}
public class TestClass
{
public int Value1 = 10;
}
[XmlType("TestClass")]
public class TestClass1
{
public int Value1 = 20;
public int Value2 = 30;
}
}
运行结果为
10, 30
说明反序列化过程中可以自动跳过缺失 XML 元素的属性/字段。
字典
XML 序列化不支持所有实现 IDictionary 接口的类。
可以替代的方法:自定义XML序列化Dictionary<int, string=””>
循环引用
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
private static void Main(string[] args)
{
var f = new XmlSerializer(typeof(TestClass));
using (var sw = new StringWriter())
{
var tc = new TestClass();
tc.MyList = new List<MyClass>(){new MyClass(), new MyClass()};
tc.Ref = tc.MyList[0];
f.Serialize(sw, tc);
Console.WriteLine(sw.ToString());
}
}
}
public class TestClass
{
public List<MyClass> MyList;
public MyClass Ref;
}
public class MyClass
{
public int Value;
}
}
运行结果如下
<?xml version="1.0" encoding="utf-16"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyList>
<MyClass>
<Value>0</Value>
</MyClass>
<MyClass>
<Value>0</Value>
</MyClass>
</MyList>
<Ref>
<Value>0</Value>
</Ref>
</TestClass>
`XmlSerializer`对循环引用处理的方法为按值展开。要解决这一问题,可以手动实现`IXmlSerializable`,或者使用`DataContractSerializer`。具体的处理方法可以参考:
WCF 第六章 序列化与编码 保留引用和循环引用。
