阅读目录

介绍

  序列化是将对象状态转换为可保持或传输的形式的过程。序列化的补集是反序列化,后者将流转换为对象。这两个过程一起保证数据易于存储和传输。

.NET Framework 提供了两个序列化技术:

  • 二进制序列化保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等。远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。

  • XML 序列化只序列化公共属性和字段,并且不保持类型保真。当您希望提供或使用数据而不限制使用该数据的应用程序时,这一点非常有用。由于 XML 是开放式的标准,因此它对于通过 Web 共享数据来说是一个理想选择。SOAP 同样是开放式的标准,这使它也成为一个理想选择。

详细

  具体命名空间:

  包含可用于序列化和反序列化对象的类。(包括System.Runtime.Serialization.Formatters.Binary.BinaryFormatter,还有WCF中用到的DataContractAttribute, DataMemberAttribute)

  包含可用于将对象序列化为 XML 格式的文档或流的类。

  WCF大家很熟悉,一般的书籍都对基础的东西有很多内容的讲解,这里就对非WCF的一些序列化技巧抛个砖。

一:序列化标记

  需要序列化:[Serializable]也可以写成[SerializableAttribute]

特性“Serializable”只在“class, struct, enum, delegate”声明中有效。所以只能在类,结构体等上面标记。

  不需要序列化:[NonSerialized]也可以写成[NonSerializedAttribute]

特性“NonSerialized”只在“field”声明中有效。所以只能在字段上标记,连属性器都不行。

二:特殊情况:

  事件的标记:

[field: NonSerializedAttribute()],需要加入field标记。

  属性的标记:

其实我们叫的属性是属性器,是一对Get,Set方法。既然是方法,当然不是字段了,所以是不能序列化标记或者排除的,那我们怎么去处理某些属性不需要序列化的情况列。方法也是有的,需要把属性器中的Get,Set方法写实,即该有的字段还是得定义,不能偷懒,然后在该有的字段上面标记为不需要序列化。

三:序列化的特殊用法

  学过C#的时候,大家都知道了个值类型,引用类型的概念,也可能知道了ICloneable这个接口,这个克隆接口可以复制对象,如实例化个student,然后调用Clone()即可以得到该对线的浅层副本

  浅层克隆就是只把改对象的值类型和引用类型的地址复制了,但是,原来对象中的被引用类型的对象发生改变,比如:student类中有个classroom,classroom中的某个字段发生改变,这样克隆后的对线的classroom的值也是会变的。除非classroom这个类也实现ICloneable接口。

  序列化克隆的好处就是不用考虑浅层复制,深层复制,直接将要克隆的对象序列化,然后反序列化得到的对象就是我们期望的结果。

处理

  按照上面的说明,代码如下:

Student类

     [Serializable]
public class Student
{
[field: NonSerializedAttribute()]
public event EventHandler Changed;
[NonSerialized]
private ExParam param; public string ID
{
get;
set;
} public string Name
{
get;
set;
} public ClassRoom Room
{
get;
set;
} public ExParam Param
{
get
{
return param;
}
set
{
param = value;
}
}
}

ClassRoom类

     [Serializable]
public class ClassRoom
{ public string Name
{
get;
set;
} public string Address
{
get;
set;
}
}

ExParam类

     public class ExParam
{
public string Name
{
get;
set;
}
}

Util类

     public class Util
{
public static byte[] SerializeObject(object obj)
{
if (obj == null)
return null; using (MemoryStream memory = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memory, obj);
memory.Position = ;
byte[] read = new byte[memory.Length];
memory.Read(read, , read.Length);
memory.Close();
return read;
}
} public static object DeserializeObject(byte[] data)
{
object obj = null;
if (data == null)
return obj; using (MemoryStream memory = new MemoryStream(data))
{
memory.Position = ;
BinaryFormatter formatter = new BinaryFormatter();
obj = formatter.Deserialize(memory);
memory.Close();
return obj;
}
}
}

主窗体

  private void Form1_Load(object sender, EventArgs e)
{
Student student = new Student()
{
ID = "",
Name = "攻城狮",
Room = new ClassRoom()
{
Name = "博客园",
Address = "小山村"
},
Param = new ExParam()
{
Name = "程序猿"
}
}; byte[] data = Util.SerializeObject(student); Student student1 = Util.DeserializeObject(data) as Student; Print(student);
Print(student1);
} private void Print(Student student)
{
string info =string.Format("{0}{1}{2}{3}"
, "hashcode:" + student.GetHashCode().ToString() + " "
, student.ID + " " + student.Name + " "
, student.Room != null ? student.Room.Name + " " + student.Room.Address + " "+student.Room.GetHashCode().ToString()+" " : "room is null "
, student.Param != null ? student.Param.Name : "param is null"
);
listPrint.Items.Add(info);
}

结论

  上述代码输出:

   

从上述代码输出的结果我们可以看出

  • student是被序列化的,student1是用student的序列化的二进制反序列化出来的,两个的hashcode不一样,所以是两个对象。
  • 标记了序列化的字段都被序列化了,没标记的序列化字段Param是空的。
  • student中的属性Room是引用类型,标记为序列化,student和student1的Room里的值内容一样但是hashcode不一样,所以这Room也是我们期望的两个对象。

Demo下载

源码下载

.NET序列化的一点技巧(附Demo)的更多相关文章

  1. .NET序列化的一点技巧

    介绍 序列化是将对象状态转换为可保持或传输的形式的过程.序列化的补集是反序列化,后者将流转换为对象.这两个过程一起保证数据易于存储和传输. .NET Framework 提供了两个序列化技术: 二进制 ...

  2. Everything常见问题及搜索技巧,附Demo

    1 Everything 1.1 "Everything"是什么? "Everything"是一个运行于Windows系统,基于文件.文件夹名称的快速搜索引擎. ...

  3. C#版清晰易懂TCP通信原理解析(附demo)

    [转] C#版清晰易懂TCP通信原理解析(附demo) (点击上方蓝字,可快速关注我们) 来源:周见智 cnblogs.com/xiaozhi_5638/p/4244797.html 对.NET中网络 ...

  4. C#开发微信公众平台-就这么简单(附Demo)转载

    C#开发微信公众平台-就这么简单(附Demo)  来源:https://www.cnblogs.com/xishuai/p/3625859.html#!comments 写在前面 阅读目录: 服务号和 ...

  5. 开源分享:谷歌大佬联合打造《高级Kotlin强化实战(附Demo)》

    Kotlin 以其简洁的特性而闻名,而在我们的实践中,更加简洁就意味着更加高效.事实上,在使用 Kotlin 的专业 Android 开发者中,有多达 67% 的人表示 Kotlin 已经帮助他们提升 ...

  6. 基于socket的客户端和服务端聊天简单使用 附Demo

    功能使用 服务端 分离一个不停接受客户端请求的线程 接受不客户端请求的线程中,再分离就收消息的线程 几大对象分别是 IPEndPoint IP终结点 服务端Socket,绑定终结点Bind,启动监听L ...

  7. 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)

    转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...

  8. Asp.net MVC集成Google Calendar API(附Demo源码)

    Asp.net MVC集成Google Calendar API(附Demo源码) Google Calendar是非常方便的日程管理应用,很多人都非常熟悉.Google的应用在国内不稳定,但是在国外 ...

  9. winserver的consul部署实践与.net core客户端使用(附demo源码)

    winserver的consul部署实践与.net core客户端使用(附demo源码)   前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的 ...

随机推荐

  1. C#多线程学习笔记

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  2. Java数组排序和查找

    Java 1.2 添加了自己的一套实用工具,可用来对数组或列表进行排列和搜索.这些工具都属于两个新类的"静态"方法.这两个类分别是用于排序和搜索数组的Arrays,以及用于排序和搜 ...

  3. TreeSet集合深入了解--------攻击原理

    Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.(无序,不可重复 )Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说 ...

  4. Oracle EBS Form Builder使用Java beans创建窗体

    最近有个项目,需要研究一下Oracle的E-Business Sutie(EBS),对于以前没接触此套件的我来说,简直太痛苦了.在网上找了一堆资料,试着进行Form二次开发,也遇到各类奇葩问题.目前遇 ...

  5. 原生JS:Date对象详细参考

    Date对象:基于1970年1月1日(世界标准时间)起的毫秒数 本文参考MDN做的详细整理,方便大家参考MDN 构造函数: new Date(); 依据系统设置的当前时间来创建一个Date对象. ne ...

  6. 原生JS:Object对象详细参考

    Object对象详细参考 本文参考MDN做的详细整理,方便大家参考MDN JavaScript原生提供一个Object对象(注意起首的O是大写),所有其他对象都继承自这个对象. 构造函数: Objec ...

  7. javascript 函数初探 (六)--- 闭包初探#1

    首先我们来看一个函数: var a = 'global variable'; var F = function(){ var b = 'local variable'; var N = functio ...

  8. 利用Canvas实现360度浏览

    前言:最近几个月来到新公司,主要从事移动端方面的开发,有时候也挺忙挺累的,于是就好一段时间没写博客了.其实自己在这几个月里,自己对canvas以及createjs和egret都有了一定程度上的认识与掌 ...

  9. AE,按照属性值关系选择要素

    if(axMapControl2.LayerCount<=0) { MessageBox.Show("请加载图层后使用该功能","系统提示",Messag ...

  10. Kotlin:Android世界的Swift

    转自:http://www.infoq.com/cn/news/2015/06/Android-JVM-JetBrains-Kotlin Kotlin是一门与Swift类似的静态类型JVM语言,由Je ...