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

换为字节流,然后再把字节流写入数据流,在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

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

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

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

当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。

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

如果对象是从 MarshalByRefObject 派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。也可以将从 MarshalByRefObject 派生得到的对象标记为 Serializable。远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换所有从 MarshalByRefObject 派生得到的对象。如果没有预先配置为 SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则(请参阅序列化过程的步骤)。

基本序列化

要使一个类可序列化,最简单的方法是使用 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平台上进行反序列化的对象,此格式化程序无疑是一个理想工具,需要注意的是:对对象进行反序列化时并不调用构造函数,对反序列化添加这项约束,是出于性能方面的考虑,但是,这违反了对象编写者通常采用的一些运行时约定,因此,开发人员在将对象标记为

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

Serializable在C#中的作用.net中的对象序列化 (转)的更多相关文章

  1. C#[Serializable]在C#中的作用-NET 中的对象序列化

    为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本:按值将对象从一个应用程序域发送至另一个应用程序域.例如,序列化可用于在 ASP.NET 中保 ...

  2. Serializable在C#中的作用——.net中的对象序列化

    序列化是指将对象实例的状态存储到存储媒体的过程,在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流,在随后对对象进行反序列化时,将创建出与 ...

  3. mvc EF框架中,加载外键对象序列化对象时报错 序列化类型为XX的对象时检测到循环引用

    Newtonsoft.Json.dll 或者通过->工具->库程序包管理工具->NuGet管理包->联机 输入Newtonsoft或者json.net Newtonsoft.J ...

  4. java类中serialversionuid 作用 是什么?举个例子说明(转)

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  5. dubbo初认知(dubbo和springCloud关系,在微服务架构中的作用等)(持续更新中)

    一:dubbo是什么? dobbuo是阿里开源的一个高性能优秀的服务框架, 可通过高性能的 RPC 实现服务的输出和输入功能,使得应用可以和 高性能的rpc实现输入和输出的功能,可以了  Spring ...

  6. [转]uboot中SPL作用

    转:http://blog.csdn.net/voice_shen/article/details/17373671 这篇文章写的非常详细 [u-boot: 2014.01-rc1] 本文将使用sam ...

  7. c++ *.h和*.cpp在编译中的作用

    首先,我们可以将所有东西都放在一个.cpp文件内.然后编译器就将这个.cpp编译成.obj,obj是什么东西?就是编译单元了. 一个程序,可以由一个编译单元组成,也可以有多个编译单元组成. 如果你不想 ...

  8. js中!!的作用

    js中!!的作用是: !!一般用来将后面的表达式转换为布尔型的数据(boolean) ===表示类型什么的全部相等(自己写一个if测试一下就好了)!==表示要全部不想等包括类型(一样写一个if)||或 ...

  9. emms指令在MMX指令中的作用

    emms指令在MMX指令中的作用 转自:http://blog.csdn.net/psusong/archive/2009/01/08/3737047.aspx MMX和SSE都是INTEL开发的基于 ...

随机推荐

  1. Cobalt Strike

    http://www.77169.com/hack/201512/222080.shtm

  2. Android 通过广播启动另一个应用的Activity

    需求:现在有应用A和应用B,我需要在A应用中启动B应用中的某个Activity 实现:A应用中的Activity发送广播,关键代码如下: String broadcastIntent = " ...

  3. P55、面试题6:重建二叉树

    题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字,例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2, ...

  4. C 可变参数(C与指针实例)

    偶尔我们需要设计一些函数,它们的参数数目不是固定的,这样我们需要用到可变参数列表. 可变参数列表是通过宏来实现的,定义于stdarg.h头文件. 具体内容在<C与指针> ;         ...

  5. 【HDOJ】4122 Alice's mooncake shop

    RMQ的基础题目,简单题. /* 4122 */ #include <iostream> #include <sstream> #include <string> ...

  6. Netfilter&iptables:如何理解连接跟踪机制?

    如何理解Netfilter中的连接跟踪机制? 本篇我打算以一个问句开头,因为在知识探索的道路上只有多问然后充分调动起思考的机器才能让自己走得更远.连接跟踪定义很简单:用来记录和跟踪连接的状态. 问:为 ...

  7. 1067. Disk Tree(字符串)

    1067 破题啊  写完发现理解错题意了 子目录下会有跟之前重名的 把输入的字符串存下来 排下序 然后依次找跟上面有没有重的 #include <iostream> #include< ...

  8. bzoj1588,1208,1503

    进入splay tree的学习中: 据说splay tree在理论上功能十分强大,好好学: splay首先一定是一棵BST,所以记不得的时候画个图就明白: 首先总结一下splay基本的操作左旋,右旋: ...

  9. [swustoj 371] 回文数

    回文数(0371) 问题描述 一个自然数如果把所有数字倒过来以后和原来的一样,那么我们称它为回文数.例如151和753357.我们可以把所有回文数从小到大排成一排:1, 2, 3, 4, 5, 6, ...

  10. 统一Matlab下不同子图的色标colorbar

    Reference:http://www.mathworks.com/matlabcentral/answers/100950-how-can-i-have-a-standard-colorbar-f ...