首先引用msdn上的内容,是关于XmlSerializer的构造函数(Type, Type[])的:
默认情况下,如果某公共属性或字段返回对象或对象数组,则将自动序列化此对象类型。但是,如果某个类包含返回Object类型的数组的字段或属性,则可以将任何对象插入此数组。在此情况下,必须指示 XmlSerializer,请求将要插入到 Object 数组的所有可能的对象类型。若要执行该操作,请使用 extraTypes 参数指定要序列化或反序列化的其他对象类型。
还可以使用 extraTypes 参数指定从基类派生的类型。例如,假设有一个名为 Phone 的基类,并且一个名为 InternationalPhone 的类从该基类派生。同时,使用 extraTypes参数来指定派生类型。
具体链接:https://msdn.microsoft.com/zh-cn/library/e5aakyae(v=vs.80).aspx
第一种使用的情况:
这里给出测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public class A
{
public string x = "aaa";
}
public class B : A
{
public int i = 1;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
public class UserInfo
{
public int userId;
public string userName;
public A a;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
UserInfo info = new UserInfo() { userId = 1, userName = "Guozhijian", a = new A() };
string s;
using (StringWriter sw = new StringWriter())
{
XmlSerializer xz = new XmlSerializer(info.GetType());
xz.Serialize(sw, info);
s = sw.ToString();
}
Console.WriteLine(s);
Console.ReadLine();
}
}
}
上面的代码是可以成功运行的,但如果将Main函数的第一句改为:
UserInfo info = new UserInfo() { userId = 1, userName = "Guozhijian", a = new B() };
则运行时会报错,原因是因为UserInfo类包含了一个被转化为派生类的基类,那么这时就到了我们主角的出场了。
将Main函数修改如下:
static void Main(string[] args)
{
Type[] types = new Type[] { typeof(B)};
UserInfo info = new UserInfo() { userId = 1, userName = "Guozhijian", a = new B() };
string s;
using (StringWriter sw = new StringWriter())
{
XmlSerializer xz = new XmlSerializer(info.GetType(),types);
xz.Serialize(sw, info);
s = sw.ToString();
}
Console.WriteLine(s);
Console.ReadLine();
}
这样又可以跑起来了!也就是说如果我们要序列化的类中,包含了一个被转化为派生类的基类,那么可以创建一个Type数组,把需要用到的派生类给它,然后再用(Type, Type[])的构造函数。
第二种使用的情况:
这里给出测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
public class UserInfo
{
public int userId;
public string userName;
public Object[] a;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
A a1 = new A();
a1.x = "a1";
A a2 = new A();
a2.x = "a2";
A[] aArray = new A[] { a1, a2 };
UserInfo info = new UserInfo() { userId = 1, userName = "Guozhijian", a = aArray };
string s;
using (StringWriter sw = new StringWriter())
{
XmlSerializer xz = new XmlSerializer(info.GetType());
xz.Serialize(sw, info);
s = sw.ToString();
}
Console.WriteLine(s);
Console.ReadLine();
}
}
}
这个是运行不了的,因为UserInfo类包含返回Object类型的数组的字段,并且我们将一个类A的数组赋值给了这个字段。那么这时我们的主角又出场了。。
将Main函数修改如下:
static void Main(string[] args)
{
Type[] types = new Type[] { typeof(A)};
A a1 = new A();
a1.x = "a1";
A a2 = new A();
a2.x = "a2";
A[] aArray = new A[] { a1, a2 };
UserInfo info = new UserInfo() { userId = 1, userName = "Guozhijian", a = aArray };
string s;
using (StringWriter sw = new StringWriter())
{
XmlSerializer xz = new XmlSerializer(info.GetType(),types);
xz.Serialize(sw, info);
s = sw.ToString();
}
Console.WriteLine(s);
Console.ReadLine();
}
这时我们的代码又可以跑了!也就是说如果我们要序列化的类中,包含了返回Object类型的数组的字段或属性,并且这个字段或属性被其他类型赋值的话,那么可以创建一个Type数组,把"其他类型"给它,然后再用(Type, Type[])的构造函数。