Serializable在C#中的做用.net中的对象序列化 (转)

序列化是指将对象实例的状态存储到存储媒体的过程,在此过程当中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转程序员

换为字节流,而后再把字节流写入数据流,在随后对对象进行反序列化时,将建立出与原对象彻底相同的副本。框架

 

在面向对象的环境中实现序列化机制时,必须在易用性和灵活性之间进行一些权衡。只要您对此过程有足够的控制能力,就可使该过程在很大程度上自动进行。例如,简单的二进制序列化不能知足须要,或者,因为特定缘由须要肯定类中那些字段须要序列化。如下各部分将探讨 .NET 框架提供的可靠的序列化机制,并着重介绍使您能够根据须要自定义序列化过程的一些重要功能。函数

 

持久存储 咱们常常须要将对象的字段值保存到磁盘中,并在之后检索此数据。尽管不使用序列化也能完成这项工做,但这种方法一般很繁琐并且容易出错,而且在须要跟踪对象的层次结构时,会变得愈来愈复杂。能够想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。工具

 

公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则经过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的全部数据成员均被写入存储媒体中。对象一般用成员变量来存储对其余实例的引用。类序列化后,序列化引擎将跟踪全部已序列化的引用对象,以确保同一对象不被序列化屡次。.NET 框架所提供的序列化体系结构能够自动正确处理对象图表和循环引用。对对象图表的惟一要求是,由正在进行序列化的对象所引用的全部对象都必须标记为 Serializable(请参阅基本序列化)。不然,当序列化程序试图序列化未标记的对象时将会出现异常。性能

当反序列化已序列化的类时,将从新建立该类,并自动还原全部数据成员的值。.net

 

按值封送 对象仅在建立对象的应用程序域中有效。除非对象是从 MarshalByRefObject 派生获得或标记为 Serializable,不然,任何将对象做为参数传递或将其做为结果返回的尝试都将失败。若是对象标记为 Serializable,则该对象将被自动序列化,并从一个应用程序域传输至另外一个应用程序域,而后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程一般称为按值封送。代理

 

若是对象是从 MarshalByRefObject 派生获得,则从一个应用程序域传递至另外一个应用程序域的是对象引用,而不是对象自己。也能够将从 MarshalByRefObject 派生获得的对象标记为 Serializable。远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换全部从 MarshalByRefObject 派生获得的对象。若是没有预先配置为 SurrogateSelector,序列化体系结构将听从下面的标准序列化规则(请参阅序列化过程的步骤)。orm

 

 

基本序列化对象

 

要使一个类可序列化,最简单的方法是使用 Serializable 属性对它进行标记,以下所示:内存

 

[Serializable] public class MyObject {    public int n1 = 0;    public int n2 = 0;    public String str = null; } 如下代码片断说明了如何将此类的一个实例序列化为一个文件:

MyObject obj = new MyObject(); obj.n1 = 1; obj.n2 = 24; obj.str = "一些字符串"; IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(stream, obj); stream.Close(); 本例使用二进制格式化程序进行序列化。您只需建立一个要使用的流和格式化程序的实例,而后调用格式化程序的 Serialize 方法。流和要序列化的对象实例做为参数提供给此调用。类中的全部成员变量(甚至标记为 private 的变量)都将被序列化,但这一点在本例中未明确体现出来。在这一点上,二进制序列化不一样于只序列化公共字段的 XML 序列化程序。

将对象还原到它之前的状态也很是容易。首先,建立格式化程序和流以进行读取,而后让格式化程序对对象进行反序列化。如下代码片断说明了如何进行此操做。

IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read,FileShare.Read);

Myobject obj =(Myobject)formatter.Deserialize(stream);

stream.close()

Console.WriteLine("n1:{0}",obj.n1);

 

上面使用的BinaryFormatter效率很高,能生成很是紧凑的字节流,全部使用此格式化程序序列化的对象也可使用它进行反序列化,对于序列化将在.net平台上进行反序列化的对象,此格式化程序无疑是一个理想工具,须要注意的是:对对象进行反序列化时并不调用构造函数,对反序列化添加这项约束,是出于性能方面的考虑,可是,这违反了对象编写者一般采用的一些运行时约定,所以,开发人员在将对象标记为

可序列化时,应确保考虑了这一特殊约定。

相关文章
相关标签/搜索