要让一个对象支持.Net序列化服务,用户必须为每一个关联的类加上[Serializable]特性。如果类中有些成员不适合参与序列化(比如:密码字段),可以在这些域前加上[NonSerialized]特性。
C#支持三种序列化格式:二进制格式(使用BinaryFormatter序列化器)、SOAP格式(使用SoapFormatter序列化器)、XML格式(使用XmlSerializer序列化器)。这三种序列化器的区别如下:
二进制格式可序列化一个类型的所有可序列化字段,不管它是公共字段还是私有字段。SOAP格式和XML格式仅能序列化公共字段或拥有公共属性的私有字段,未通过属性公开的私有字段将被忽略。
使用二进制格式序列化时,它不仅是将对象的字段数据进行持久化,也持久化每个类型的完全限定名称和定义程序集的完整名称(包括包称、版本、公钥标记、区域性),这些数据使得在进行二进制格式反序列化时亦会进行类型检查。SOAP格式序列化通过使用XML命名空间来持久化原始程序集信息。而XML格式序列化不会保存完整的类型名称或程序集信息。这便利XML数据表现形式更有终端开放性。如果希望尽可能延伸持久化对象图的使用范围时,SOAP格式和XML格式是理想选择。

using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Runtime.Serialization.Formatters.Binary;
using
System.Runtime.Serialization.Formatters.Soap;
using System.IO;
using System.Xml.Serialization;
namespace
CollectionSerialize
{
class
Program
{
staticvoid
Main(string[]
args)
{
//文件名称
string
fileName ="Programmers.dat";
//创建Programmer列表,并添加对象
List<Programmer> list
=new List<Programmer>();
list.Add(new Programmer("Coder1",
false,
"C"));
list.Add(new Programmer("Coder2",
false,
"C++"));
list.Add(new Programmer("Coder3",
false,
"Java"));
//创建文件流
Stream fStream =null;
fStream = FileReset(fStream, fileName);
//使用二进制序列化器
BinaryFormatter binFormat =new
BinaryFormatter();
//将list序列化到文件中
binFormat.Serialize(fStream, list);
//清空列表
list.Clear();
//重置流位置
fStream.Position =0;
//反序列化,注意要将结果转型
list =
(List<Programmer>)binFormat.Deserialize(fStream);
//输出
Print(list);
fStream = FileReset(fStream, fileName);
//使用XML序列化
//注意使用此构造器时必须在第一个参数传入序列化的类型,第二个参数传入序列化所涉及的相关类型
XmlSerializer xmlFormat =
new
XmlSerializer(typeof(List<Programmer>),
new
Type[] { typeof(Programmer),
typeof(Person)
});
//反序列化
xmlFormat.Serialize(fStream,
list);
list.Clear();
fStream.Position =0;
//反序列化,注意要将结果转型
list =
(List<Programmer>)xmlFormat.Deserialize(fStream);
Print(list);
fStream
=
FileReset(fStream, fileName);
//使用SOAP序列化
SoapFormatter soapFormat =new
SoapFormatter();
//序列化,Soap不能序列化泛型对象,所以只能指定序列化一个Programmer对象
soapFormat.Serialize(fStream, list[0]);
list.Clear();
fStream.Position
=0;
//反序列化
list.Add((Programmer)soapFormat.Deserialize(fStream));
Print(list);
fStream.Close();
Console.ReadKey();
}
//输出程序员列表
staticvoid
Print(List<Programmer>
list)
{
Console.WriteLine("程序员信息列表:");
foreach
(Programmer p in
list)
{
Console.WriteLine("姓名:{0} 性别:{1} 编程语言:{2}",
p.Name, p.Sex.ToString(),
p.Language);
}
}
//重置文件
static
FileStream FileReset(Stream fStream, string
fileName)
{
//关闭文件流
if
(fStream !=null)
{
fStream.Close();
}
//删除文件
File.Delete(fileName);
//新建文件流
returnnew
FileStream(fileName, FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.None);
}
}
[Serializable] //必须添加序列化特性
publicclass
Person
{
//姓名
publicstring
Name;
//性别
publicbool
Sex;
//必须提供无参构造器,否则XmlSerializer将出错
public
Person() { }
//构造函数
public
Person(string
name, bool
sex)
{
this.Name
=
name;
this.Sex
=
sex;
}
}
[Serializable] //必须添加序列化特性
publicclass
Programmer : Person
{
//编程语言
publicstring
Language;
//必须提供无参构造器,否则XmlSerializer将出错
public
Programmer() { }
//构造函数
public
Programmer(string
name, bool
sex, string
language)
: base(name, sex)
{
this.Language =
language;
}
}
}

1.
SoapFormatter不能序列化泛型对象。
2.
XmlSerializer的构造器需要传入序列化涉及的相关类型信息。