C# 运行时序列化
一. 序列化与反序列的作用
为什么要有序列化呢,考虑下面这种情况,在WINFORM或者更为方便的WPF工程中,当我们进行UI设计时,可以随意的将一个控件剪切/张贴到另外一个地方。操作方便的背后是什么在发挥作用呢。控件明明是一个复杂的对象,却可以进行剪切张贴。这其中就涉及到了对象的转换。将控件这个复杂的对象转换为字节流,进行复制,然后再将字节流反转为控件对象。这样就实现了控件的随意剪切与张贴。
上述就体现了序列化的应用场合,数据传送。
定义:
序列化:将对象转换为字节流。
反序列化:将字节流转换为对象。
二.使用序列化
三.设计类可序列化,控制类的成员可序列化
1.类可序列化:
类默认是不可序列化的,但是我们在设计一个类时通常需要将其设计为可序列化,方便后续使用。使类可序列化的方法很简单,引入Attribute。在类前面加上[Serializable](是System命名空间,而不是System.Runtime.Serialization命名空间)。这样类就可序列化了。因为设置类可序列化后,默认类中的所有字段都是可序列化的。而不论其是private,protected。这样对于一些需要保护的字段就极其不利了。所以接下来就是控制类的成员可序列化。
2.控制类的成员可序列化
类型中有些字段是不希望其序列化
- 反序列化后没有意义。比如Windows内核(文件,进程,线程等)这些与进程有关,反序列化后不是同一进程,得到的信息没有意义。而序列化的目的是在于将对象转化为字节流,最终还是需要进行反序列化得到原有结果的。
- 字段可以通过简单计算得到。这样的字段没必要进行序列化。序列化反而会增加传送的数据量。
那么如何控制字段不可序列化呢
- 字段前加上[NonSerialized]即可。但是问题来了,这样我们反序列化就得不到这个字段的原有值了。像上面所述的【能够通过简单计算】得到的字段我们不希望他序列化,但设置了[NonSerialized],这样反序列后得不到想要的值。这样显然也不是我们希望看到的。解决办法就是使用[OnDeserialized]特性
- OnDeseriablized(StreamContext context)方法中重新计算标记为未序列化字段,因为有OnDeserialized特性,这样序列格式化器就会识别这个特性,对这个方法进行调用。类似的特性还有OnDeserializing,OnSerializing,OnSerialized。分别在序列化和反序列的不同时期调用。可以根据实际情况来添加对应的方法。看似已经解决了控制类的成员可序列化的问题了。但是又有一个新的问题。如果我现在在类型里添加新的字段。序列化格式化器处于性能的考虑,不会在一开始进行了字段是否可序列化的检查。而是调用时看是否能够序列化。序列化一个对象图时,只要有一个对象不能序列化【注意不是不可序列化】就会报异常。那么如果我们序列化一个类型的实例,在类型中添加新字段,然后反序列化不包含新字段的对象。那肯定会报错
- 解决2最后的问题,就可以通过OptionalFieldAttribute特性。这样格式化器就会识别这个特性,不会因为流中不包含这个字段而报错
四. 格式化器如何工作
无论是序列化,还是反序列化,还是识别特性OnSerialized等,都是格式化器在起作用。那么格式化是如何进行序列化与反序列化呢
序列化:
- 格式化器调用FormatterServices的GetSerializableMembers()方法,获取到需要序列化的字段
- 格式化器根据1取得的序列化字段调用FormatterServices的GetObjectData取得字段的对应值
- 格式化将程序集标示和类型名写入流中。
- 将1,2,取得的序列化字段和值写入流中。
反序列化:
- 读取程序集和类型名称,加载程序集
- 为对象分配内存。调用FormatterServices的Get'UninitzlizedObject()
- 初始化字段
- 初始化字段对应的值
- 将分配的对象,字段,字段对应值引用传递给FormatterServices的PopulateObjectMembers()方法
C# 运行时序列化的更多相关文章
- 《CLR Via C#》读书笔记:24.运行时序列化
一.什么是运行时序列化 序列化的作用就是将对象图(特定时间点的对象连接图)转换为字节流,这样这些对象图就可以在文件系统/网络进行传输. 二.序列化/反序列化快速入门 一般来说我们通过 FCL 提供的 ...
- 重温CLR(十八) 运行时序列化
序列化是将对象或对象图转换成字节流的过程,反序列化是将字节流转换回对象图的过程.在对象和字节流之间转换是很有用的机制. 1 应用程序的状态(对象图)可轻松保存到磁盘文件或数据库中,并在应用程序下次运行 ...
- clr via c# 运行时序列化
1,快速了解序列化----windows IO 系统,FileStream,BinaryFormatter,SoapFormatter--不支持泛型. public class SerializeRe ...
- 【C#进阶系列】24 运行时序列化
序列化是将对象或者对象图(一堆有包含关系的对象)转换成字节流的过程.而反序列化就是将字节流转为对象或对象图. 主要用于保存.传递数据,使得数据更易于加密和压缩. .NET内建了出色的序列化和反序列化支 ...
- (47)C#运行时序列化
序列化是将对象或对象图转化成字节流的过程.反序列化是将字节流转换回对象图的过程.
- ASP.NET 5运行时升级到Beta5
在Visual Studio 2015 RTM和Windows 10正式发布之前,微软把开源.NET升级到了beta5,带来了一些增强和改变.和Visual Studio 2015 RC一起安装的AS ...
- 1.2 - C#语言习惯 - 用运行时常量readonly而不是编译期常量const
C#中有两种类型的常量:编译期常量和运行时常量.二者有着截然不同的行为,使用不当将会带来性能上或正确性上的问题. 这两个问题最好都不要发生,不过若难以同时避免的话,那么一个略微慢一些但能保证正确的程序 ...
- Objective-C Runtime 运行时之一:类与对象
Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...
- Objective-O Runtime 运行时初体验
Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...
随机推荐
- TypeScript: Week Reflection
TypeScript: Week Reflection Introduction Type Script already provide decorators to help developers i ...
- js中对象的自定义排序
//并返回一个可以用来对包含该成员的对象数组进行排序的比较函数 var compareAsc = function (prop) { return function (obj1, obj2) { va ...
- 传统方法过渡到ES6去优雅地实现JavaScript的继承
众所周知,面向对象编程有三个重要的概念: 封装.继承.多态.而JS作为面向对象的弱类型语言,应该说是基于对象的语言,正如常说的,JS的世界里,万物皆对象.虽然JS本身不是面向对象的语言,我们可以通过模 ...
- 谷歌刚发布的求梯度的工具包-Tangent
安装很简单sudo pip install tangent. 我机器上,终端上用python,tangent报错,但在终端上用ipython,tangent不报错. 我检验是否可用tangent的方法 ...
- WUOJ-ACM :1003: 零起点学算法78——牛牛
武汉科技大学ACM :1003: 零起点学算法78--牛牛Problem Description牛牛是一种纸牌游戏,总共5张牌,规则如下: 如果找不到3张牌的点数之和是10的倍数,则为没牛: 如果其中 ...
- Noip2017 普及 T3 Chess
神奇的场上原码 #include<iostream> #include<cstdio> #include<cstring> #include<queue> ...
- 全局变量&局部变量,global&nonlocal
###全局变量与局部变量 1.函数内部的变量名如果第一次出现,且出现在=前面,即被视为定义一个局部变量,不管全局域中有没有用到该变量名,函数中使用的将是局部变量 2.函数内部的变量名如果第一次出现,且 ...
- seaborn使用(绘图函数)
seaborn使用(绘图函数) 数据集分布的可视化 分类数据的绘图 线性关系可视化 一.数据集分布的可视化 distplot kdeplot rugplot 1.distplot() 灵活的绘制单变量 ...
- Docker 镜像
Docker 镜像就是一个只读的模板. 例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序. 镜像可以用来创建 Docker 容器. D ...
- TensorFlow入门和示例分析
本文以TensorFlow源码中自带的手写数字识别Example为例,引出TensorFlow中的几个主要概念.并结合Example源码一步步分析该模型的实现过程. 一.什么是TensorFlow 在 ...