C#对象序列化(2)
解析
对象序列化可以使对象的数据持久地保存,对象状态可以是Ssytem.IO.Stream的派生类型。并不是任何类型的对象都可以被序列化的,只有当其类型定义为可序列化时,该对象才可以被序列化。例如,自定义一个类类型,当该类类型被标记了[Serializable]特性后,其对象即可被序列化。序列化的代码本身很简单,并可使用多种格式保存对象(或对象图),如二进制格式、SOAP格式和XML格式。
将对象以二进制格式序列化,需要使用BinaryFormatter类型,该类型位于mscorlib.dll程序集,使用时只需导入其命名空间即可,程序代码如以下代码所示:
//导入BinaryFormatter类的命名空间 //创建BinaryFormatter类对象MyBF |
可见,只需调用BinaryFormatter类对象的Serialize()方法,即可完成序列化的操作。如果使用SOAP格式序列化,其操作和二进制格式基本一致,只是由SoapFormatter类的对象调用Serialize()方法。由于定义SoapFormatter类的命名空间是System.Runtime. Serialization.Formatters.Soap,而这个命名空间定义于System.Runtime.Serialization. Formatters.Soap.dll程序集内,所以使用SoapFormatter类时,需手动引用该程序集,然后导入该命名空间。实际上,BinaryFormatter类和SoapFormatter类都实现了IFormatter接口,所以在程序应用中,可以编写相应的多态程序。
XML格式序列化对象需要创建System.Xml.Serialization.XmlSerializer类对象,然后调用Serialize()方法。该类的命名空间虽然定义于System.Xml.dll程序集内,但是Visual Studio 2005/ Visual Studio 2008将自动引用该程序集,所以不需要手动引用System.Xml.dll程序集。XML格式序列化的方法如以下代码所示:
//导入XmlSerializer类的命名空间 //创建XmlSerializer类对象MyXS |
XmlSerializer类的构造函数需要传递参数,当只需要实现一个独立对象时,传递该对象所属类的Type对象类型即可,当该对象依赖于其他对象时,需要将其他对象所属类的Type对象类型作为数组传递。
说明:对象图是指一组关联的对象关系图,描述了多个对象之间的依赖关系。
面试例题21:如何将XML格式持久化的对象反序列化?
考点:反序列化的基本方法,处理反序列化后的对象数据。
出现频率:★★
解答
在Visual Studio 2005/ Visual Studio 2008中创建一个C#的Windows窗体应用程序项目,并将其项目命名为ListSerialize。程序序列化的对象是List<T>类的对象(该类是可序列化的),通过"添加"按钮控件,增加List<T>类对象中的子项,直到单击"输出XML"按钮。而单击"XML反序列化"按钮后,指定XML文件中的对象信息还原,并在ListBox控件(命名为"XmlList")中输出该对象的每个子项数据。在Visual Studio 2005/ Visual Studio 2008的"Form1.cs[设计]"视图中创建基本的窗体布局和控件,控件的命名如图7.50所示。
(点击查看大图)图7.50 反序列化程窗体控件布局及命名 |
编写ListSerialize项目的Form1.cs如代码7.26所示。
代码7.26 反序列化对象:Form1.cs
using System;
namespace ListSerialize
private void AddBtn_Click(object sender, EventArgs e)
private void OutputBtn_Click(object sender, EventArgs e)
private void InputBtn_Click(object sender, EventArgs e)
public class PersonDetail |
程序运行后,在前两个"TextBox"控件中输入一组值并单击"添加"按钮,结果如图7.51所示。
用户每单击一次"添加"按钮,list对象中将添加一个子项,该子项是根据用户输入值初始化的PersonDetail类的对象。当子项添加操作完成后,程序弹出如图7.51所示的信息对话框。进行多次添加操作后,在Name属性为"ReadFileName"的文本框控件输入任意XML文件的文件名,单击"输出XML"按钮,即可完成XML格式的序列化操作。可将序列化操作创建的XML文件名再次输入到Name属性为ReadFileName的文本框控件中,然后单击"XML反序列化"按钮即可完成该XML文件中数据的反序列化操作,运行结果如图7.52所示。
图7.51 以XML格式序列化 |
(点击查看大图)图7.52 反序列化XML文件并输出 |
根据输入值,创建的list对象数据已经被成功反序列化,并且在Name属性为"XmlList"的列表框控件中显示。
解析
反序列化是序列化的逆向操作,既然序列化操作需要写入到流,反序列化即读取流并将对象数据提取出来。例如,在程序集相同目录下有一个"Person.dat"文件,该文件以二进制格式持久化已知类型(如PersonName类)的对象,其反序列化的方法如以下代码所示:
//导入BinaryFormatter类的命名空间 //创建BinaryFormatter类对象MyBF |
以上代码中,程序获得了PersonName类对象的引用Pn,该对象根据"Person.dat"文件反序列化创建,还原原对象的数据。
面试例题22:如何自定义序列化?
考点:理解自定义序列化,学习自定义序列化方法。
出现频率:★★★★
解答
在Visual Studio 2005/ Visual Studio 2008中创建一个C#的Windows窗体应用程序项目,并将其项目命名为CustomSerialize。程序可以根据用户输入值创建一个对象,以二进制格式序列化对象,并持久化到指定的路径。这个过程,对象的字段值将被添加一段字符串,并且其字段值对应的键名也被修改为指定值,而不是字段名称。在反序列化的过程中,对象的字段数据值被修改为原始值,所以看上去对象数据没有作任何修改。在Visual Studio 2005/Visual Studio 2008的"Form1.cs[设计]"视图中创建基本的窗体布局和控件,控件的命名如图7.53所示。
(点击查看大图)图7.53 自定义序列化窗体控件布局及命名 |