通过上面的流类型可以方便地操作各种字节流,但是如何把现有的实例对象转换为方便传输的字节流,就需要使用序列化技术。对象实例的序列化,是指将实例对象转换为可方便存储、传输和交互的流。在.NET中,通过Serializable特性提供了序列化对象实例的机制,当一个类型被申明为Serializable后,它就能被诸如BinaryFormatter等实现了IFormatter接口的类型进行序列化和反序列化。.
[Serializable]
public class Person
{
......
}
但是,在实际开发中我们会遇到对于一些特殊的不希望被序列化的成员,这时我们可以为某些成员添加NonSerialized特性。例如,有如下代码所示的一个Person类,其中number代表学号,name代表姓名,我们不希望name被序列化,于是可以为name添加NonSerialized特性:
public class Program
{
public static void Main(string[] args)
{
Person obj = new Person(26, "Edison Chou");
Console.WriteLine("初始状态:");
Console.WriteLine(obj);
// 序列化对象
byte[] data = Serialize(obj);
// 反序列化对象
Person newObj = DeSerialize(data);
Console.WriteLine("经过序列化和反序列化后:");
Console.WriteLine(newObj);
Console.ReadKey();
}
// 序列化对象
static byte[] Serialize(Person p)
{
// 使用二进制序列化
IFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, p);
return ms.ToArray();
}
}
// 反序列化对象
static Person DeSerialize(byte[] data)
{
// 使用二进制反序列化
IFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
Person p = formatter.Deserialize(ms) as Person;
return p;
}
}
}
上述代码的运行结果如下图所示:

注意:当一个基类使用了Serializable特性后,并不意味着其所有子类都能被序列化。事实上,我们必须为每个子类都添加Serializable特性才能保证其能被正确地序列化。