序列化和反序列化

相关类:

System.SerializableAttribute特性(或称为属性),

System.Runtime.Serialization.ISerializable(自定义序列化接口)

https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.iserializable.aspx,

System.Runtime.Serialization.IserializationSurrogate(自定义序列化代理接口),

System.Runtime.Serializatin.SurrogateSelector(自定义序列化代理设置类)

1:官方备注

序列化使用

BinaryFormatter(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx)或

SopaFormatter(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.soap.soapformatter.aspx),使用方法类同。

System.SerializableAttribute特性:

将SerializableAttribute特性应用于一个类型可指示该类型的实例可以序化。如果正在序列化的对象图中的任何类型未应用SerializableAttribute特性,公共语言运行时则会引发SerializableException(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.serializationexception.aspx)。

即使该类会实现ISerializable接口来控制序列化进程,仍要应用SerializableAttribute特性。

将SerializableAttribute特性应用于类型时,序列化默认情况下所有私有和公共字段。

也可以从序列化排除字段通过应用NonSerializedAttribute(https://msdn.microsoft.com/zh-cn/library/system.nonserializedattribute.aspx)特性应用于字段。如果可序列化类型的字段包含指针、句柄或其他模型针对于特定环境的数据结构,并且不能在不同的环境中以有异议的方式重建,则最好经NonSerializableAttribute特性应用于该字段。

System.Runtime.Serialization.ISerializable接口:

任何可以序列化的类都必须用SerializableAttribute进行标记。如果某个类需要控制器序列化进程,它可以实现ISerializable接口。Formatter(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatter.aspx)在序列化时调用GetObjectData,并使用表示对象所需的全部数据来填充所提供的SerializationInfo(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.serializationinfo.aspx)。Formatter使用图形中对象的类型来创建SerializationInfo。需要自己发送代理的对象可以使用SerializationInfo上的FullTypeName和AssemblyName属性来更改所传输的信息,或直接使用方法SetType,与同时设置FullTypeName和AssemblyName等效。

在类继承的情况下,可以序列化从实现ISerializable的基类中派生的类。这种情况下,派生的类应在GetObjectData的实现内调用GetObjectData的基类实现。否则,不会序列化来自基类的数据。

ISerializable接口需要带有签字(SerializationInfo,StreamingContext)的构造函数。在反序列化时,仅在格式化程序已反序列化SerializationInfo中的数据后才调用当前构造函数。一般而言,如果该类未密封,则应保护此构造函数,序列化过程会忽略此构造方法的访问修饰符,及应当使用protected或private(类被sealed修饰时)来修饰此构造方法。

无法保证对象被反序列化的顺序。例如,如果一种类型引用尚未反序列化的类型,则会引发异常。如果创建具有这种依赖关系的类型,可以通过IDeserializationCallback(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.ideserializationcallback.aspx)接口和OnDeserialization方法来解决该问题。

序列化接口处理像处理扩展Object的类型一样,处理扩展MarshalByRefObject(https://msdn.microsoft.com/zh-cn/library/system.marshalbyrefobject.aspx)的对象类型。这些类型都可以使用SerializableAttribute来标记,并且可以将ISerializable接口实现为其他任何对象类型。它们的对象状态将被捕获并在流中持续。

当通过System.Runtime.Remotting使用这些类型时,远程处理接口会提供一个代理项,它将取代常用的序列化,而将代理序列化为MarshalByRefObject。代理项是知道如何将特定类型的对象序列化和反序列化的帮助器。代理在大多数情况下对用户不可见,其类型将是ObjRef(https://msdn.microsoft.com/zh-cn/library/system.runtime.remoting.objref.aspx)。

作为一种常规的设计模式,类很少既使用可序列化特性来标记,又扩展MarshalByRefObject。当组合这两项特性时,开发人员应仔细考虑可能的序列化和远程处理方案。MemoryStream就是一个适用的示例。当MemoryStream的基类从MarshalByRefObject扩展时,可以捕获MemoryStream的状态并随时将其还原。因此,这样做可能是有意义的:将该流的状态序列化到数据库中,并在稍后某一时间将其还原。但是,当通过远程处理来使用时,这种类型的对象将设置代理。

有关序列化MarshalByRefObject的派生类的更多信息,请参见RemottingSurrogateSelector(https://msdn.microsoft.com/zh-cn/library/system.runtime.remoting.messaging.remotingsurrogateselector.aspx)。

关于如果实现ISerializable的更多信息,请参见自定义序列化(https://msdn.microsoft.com/zh-cn/library/ty01x675.aspx)。

System.Runtime.Serialization.ISerializationSurrogate接口:

实现序列化代理选择器,此选择器允许一个对象对另一个对象执行序列化和反序列化。

System.Runtime.Serializatin.SurrogateSelector类:

序列化代理项将为用户提供一种对象,该对象可以处理不同对象的序列化要求,并且可以再必要时转换序列化数据。该类实现接口System.Runtime.Serializatin.ISurrogateSelector。

System.Runtime.Serializatin.ISurrogateSelector接口:

实现该接口的类可用于选择代理项,以使用该代理项的序列化和反序列方法对其他类进行序列化或序列化操作。

2:简单序列化

需要使用的类有SerializableAttribute特性,和BinaryFormatter,对于不需要或不应序列化的类成员需用NonSerializableAttribute特性修饰。

代码如下:

[Serializable]

public class MyItemType{

//其他成员…

[NonSerializable]

public string IgnorField{…}

}

//序列化过程

string fileName = “[文件名]”;

MyItemType t = new MyItemType();

FileStream fs = new FileStream(fileName,FileMode.Create);

IFromatter formatter = new BinaryFormatter();

formatter.Serialize(fs, t);

fs.Close();

//反序列化过程

string fileName =  “[文件名]”;

MyItemType result = null;

FileStream fs = new FileStream(fileName, FileMode.Open);

IFormatter formatter = new BinaryFormatter();

result = formatter.Deserialize(fs);

fs.Close();

3:使用ISerializable接口实现自定义序列化

继承ISerializable接口需实现方法GetObjectData,并添加一个具有签名SerializationInfo info和StreamingContext context的构造方法以供反序列化使用,须注意的是此构造方法的访问修饰符在反序列化过程中将被忽略,因此为防止此构造方法被错误的调用应对其使用较严格的访问修饰符比如protected或private。

实现此接口的类也应当使用SerializableAttribute修饰。

代码实例:

[Serializable]

public class MyItemType:Isereializable

{

//字段….

#region 自定义序列化

private MyItemType(SerializationInfo info, StreamingContext context)

{

ThisObjectStringField = info.GetValue(“keyName”, typeof(string));

ThisObjectIntField = info.GetInt32(“keyName2”);

}

public override void GetObjectData(SerializationInfo info, StreamingContext context)

{

info.AddValue(“keyName”, ThisObjectStringField, typeof(string));

//info.AddInt32(“keyName”, ThisObjectIntField);//此行错误,info没有强类型的值添加方法

}

#endregion

}

//使用方法同于简单序列化代码实例中的使用方法

4:使用IserializationSurrogate接口实现的序列化代理项

使用IserializationSurrogate实现类可对另一个类进行序列化和反序列化。

此序列化方式使用到的类或接口还包括对代理项选择的SurrogateSelector类,Iformatter实现类(此处使用BinaryFormatter)

示例代码:

//自定义序列化代理

public class Surrogate : ISerializationSurrogate

{

public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)

{

if (obj is MyItemType)

{

MyItemType temp = (MyItemType)obj;

info.AddValue("props", temp, typeof(string));

}

}

public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)

{

if (obj is MyItemType)

{

MyItemType temp = (MyItemType)obj;

temp.MyProperty = (string)info.GetValue("props", typeof(string));

Console.WriteLine("SetObjectData");

return temp;

}

return null;

}

//使用方法

Surrogate surrogate = new Surrogate();

SurrogateSelector selector = new SurrogateSelector();

selector.AddSurrogate(typeof(MyItemType), new StreamingContext(StreamingContextStates.All), surrogate);

formatter.SurrogateSelector = selector;

FileStream fs = new FileStream(fileName, FileMode.Open);

formatter.Deserialize(fs);

fs.Close();

//总结时间:2015-03-17

//修改时间:2015-03-23

C#序列化与反序列化方式简单总结的更多相关文章

  1. Java:对一个对象序列化和反序列化的简单实现

    名词解释 序列化:将Java对象转化成字节的过程 反序列化:将字节转化成Java对象的过程 字节:1字节(byte)= 8bit,bit就是计算机认识的二进制 序列化的作用 Java对象是在Java虚 ...

  2. C#中的Json的序列化和反序列化

    Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...

  3. 第一章 JacksonUtil 序列化与反序列化属性总结

    1.json-lib与Jackson 关于json-lib与Jackson对比总结如下: 1).性能方面,Jackson的处理能力高出Json-lib10倍左右. 2).json-lib已经停止更新, ...

  4. 序列化、反序列化和transient关键字的作用

    引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口, ...

  5. .Net类的序列化和反序列化 - 进阶者系列 - 学习者系列文章

    今天看了下以前的一个工具的代码,其中涉及到.NET类的序列化和反序列化问题,所以就写一下. 这里说一下.NET类序列化的好处..NET类在序列化之前只是一个相对狭义的类.通过序列化,能够更好的保存该类 ...

  6. java梳理-序列化与反序列化

    一背景: 之前笔记关于rpc框架介绍中,提到为了调用远程服务,需要再确定消息结构后考虑序列化与反序列化,序列化主要是把对象转换成二进制码便于网络传输,反序列化就是相反的,主要目的是生成对象便于后续处理 ...

  7. .Net中的序列化和反序列化详解

    序列化通俗地讲就是将一个对象转换成一个字节流的过程,这样就可以轻松保存在磁盘文件或数据库中.反序列化是序列化的逆过程,就是将一个字节流转换回原来的对象的过程. 然而为什么需要序列化和反序列化这样的机制 ...

  8. 浅谈C#中的序列化与反序列化

    今天我利用这篇文章给大家讲解一下C#中的序列化与反序列化.这两个概念我们再开发中经常用到,但是我们绝大部分只用到了其中的一部分,剩下的部分很多开发人员并不清楚,甚至可以说是不知道.因此我希望通过这篇文 ...

  9. Java 中序列化与反序列化

    一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...

随机推荐

  1. 作业七:团队项目——Alpha版本冲刺阶段008

    今日进度:组内成员讨论 今日安排:组内成员分工

  2. 使用JavaScript的history对象来实现页面前进后退(go/back/forward)。

    我们都知道JavaScript有history对象,主要是用来记录浏览器窗口的浏览记录.但是,JS脚本是不允许访问到这个记录里面的内容(隐私). 常见的用法是: history.back();//返回 ...

  3. github代码收集推荐

    https://github.com/AFNetworking/AFNetworkinghttps://github.com/jessesquires/JSQMessagesViewControlle ...

  4. 构造一个简单的Linux系统MenuOS

    陈智威20135125 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验指导 ...

  5. PKU 1006

    数学问题吧,有兴趣的可以研究一下“中国剩余定理” // 1006.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include < ...

  6. spring 包下载地址

    留着,以备不时之需: http://repo.spring.io/libs-release-local/org/springframework/spring/

  7. JSP九大内置对象的作用和用法总结?

    JSP九大内置对象的作用和用法总结? 1.request对象javax.servlet.http.HttpServletRequest request对象代表了客户端的请求信息,主要用于接受通过HTT ...

  8. 软件工程总结(Final)

    又到了学期末了,此时此刻软件工程课业接近尾声了.时间过得太快,仿佛昨天这学期的课才开始, 开学时,老师让我们提出了不少对这门课的问题和疑惑,通过一学期的努力学习,我可以试着解开我自己的疑问了. 下面是 ...

  9. 易图软件之EaseMap Desktop 1.0发布

    概述 易图软件之EaseMap Desktop 1.0是一款基于arcgis runtime for wpf开发的地图编辑软件. 软件代码编写历时1个月终于完成. 目前这个版本的功能包括: 地图基本操 ...

  10. Javascript 特效(一)返回顶部

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...