一个关于反序列化的小问题
大家都知道,我们具有三种定义可序列化类型的方式:在类型上应用SerializableAttribute特性;应用DataContractAttribute/DataMemberAttribute特性和实现ISerializable接口。当你通过继承一个现有的类来定义你需要被序列化的类,如果这个父类实现了ISerializable接口,如果定义不当,就会出现反序列化的问题。而且这个我们可能经常都不注意。
一、问题重现
首先,我想自定义一个字典类型MyDictionary,其Key和Value的类型分别为String和Object。最简单的方式莫过于直接继承Dictionary<string, object>。为了让MyDictionary对象可序列化,我们在类型上面应用了SerializableAttribute特性。MyDictionary定义如下:
1: [Serializable]
2: public class MyDictionary : Dictionary<string, object>
3: {
4: }
然后我通过下面的代码对MyDictionary对象进行序列化和反序列化,我直接采用的序列化器为BinaryFormatter。
1: static void Main(string[] args)
2: {
3: var dictionary = new MyDictionary();
4: dictionary.Add("001", "Foo");
5: dictionary.Add("002", "Bar");
6: dictionary.Add("003", "Baz");
7:
8: using (MemoryStream stream = new MemoryStream())
9: {
10: var formatter = new BinaryFormatter();
11: formatter.Serialize(stream, dictionary);
12: stream.Seek(0, 0);
13: dictionary = (MyDictionary)formatter.Deserialize(stream);
14: }
15:
16: foreach (var item in dictionary)
17: {
18: Console.WriteLine("{0}: {1}", item.Key, item.Value);
19: }
20: }
现在我们运行这段代码,在进行但序列化的时候出现如下SerialiationException的异常,错误消息提示找不到构造函数。
二、解决问题
通过上面的截图,我们可以看到具体的错误消息:“The constructor to deserialize an object of type 'DeserializationIssue.MyDictionary' was not found.”,对于这个消息,我们第一个反应是在反序列化的时候找不到默认(无参)的构造函数。但是再看MyDictionary的定义,我们不曾定义任何构造函数,意味着它具有一个默认(无参)构造函数。
实际上,这里并不是找不到默认(无参)构造函数,而是找不到一个具有特殊参数列表的构造函数。该构造函数接收两个参数,类型分别是:SerializationInfo和StreamingContext。所以我们的解决方案很简单,就是加上这么一个构造函数。为此我们从新定义MyDictionary。
1: [Serializable]
2: public class MyDictionary : Dictionary<string, object>
3: {
4: public MyDictionary() { }
5: protected MyDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
6: }
从新运行我们的程序,你就会得到想要的输出结果:
1: 001: Foo
2: 002: Bar
3: 003: Baz
如果一个类型实现了ISerializable接口(Dictionary<TKey, TValue>就实现了这个接口),你就应该定义如上一个构造函数。这算是一个约定,但是当你继承某个类型的时候,你往往会忘记这个约定。
转载于:https://www.cnblogs.com/artech/archive/2011/04/14/SerializationIssue.html
一个关于反序列化的小问题相关推荐
- 2020-2-15一个web登录注册小程序与Spring初始+作业
文章目录 建立一个Web登录注册小程序 1.先在Mysql数据库中新建一个数据库 2.在IDEA中新建一个工程 3.对项目进行简单分层 4.设计一个实体类 5.引入一个jdbc工具类 6.写一个测试类 ...
- WPF 一个训练记忆力的小游戏——记忆联盟
WPF 一个训练记忆力的小游戏--记忆联盟 一.简述 记--一个用来训练记忆力的小游戏--记忆联盟. 例子打包:https://wwa.lanzous.com/iM4ZDllmjzi (2 ...
- python井字棋_用Python做一个井字棋小游戏
井字棋是一个经典的小游戏,在九宫格上玩家轮流画OXO,当每列或每行或是两个对角成一线时便是获胜. 今天就用Python编写一个井字棋小游戏,与电脑对战. 程序执行画面如下图所示: 程序提供了两种人工智 ...
- html中图片只是一个小图标,如何用css显示一个图片中多个小图标?
去搜一下css中background的用法,一切尽在其中. 最重要的一点是 你要了解背景图片在控制项中显示的起始位置,控制项的高度,宽度. 以下是简要分析,你还要实践一下才能掌握真谛: 对一个宽度40 ...
- python软件代码示例-用Python写一个模拟qq聊天小程序的代码实例
Python 超简单的聊天程序 客户端: import socket, sys host = '10.248.27.23' # host = raw_input("Plz imput des ...
- OpenCV的HSV空间度量与标准HSV不一样,使用的时候需要换算;另附一个调色取色的小工具
图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 在对图像的颜色进行处理时,RGB通道并不能很好地 ...
- python简单小游戏代码_一个简单的python小游戏---七彩同心圆
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 用pygame做一个简单的python小游戏-七彩同心圆 玩法:每次点击鼠标时,会以鼠标为圆心,不断 ...
- 利用 C# 中的 FileSystemWatcher 制作一个文件夹监控小工具
利用 C# 中的 FileSystemWatcher 制作一个文件夹监控小工具 独立观察员 2020 年 12 月 26 日 前一段看到微信公众号 "码农读书" 上发了一篇文章&l ...
- 用 C# 写一个 Redis 数据同步小工具
用 C# 写一个 Redis 数据同步小工具 Intro 为了实现 redis 的数据迁移而写的一个小工具,将一个实例中的 redis 数据同步到另外一个实例中.(原本打算找一个已有的工具去做,找了一 ...
最新文章
- [C#,Java,PHP] - IMAP文件夹名称编码和解码方法
- JMeter正则表达式-学习(3)
- spring cloud各个微服务打包到docker容器内
- 后端把Long类型的数据传给前端,前端可能会出现精度丢失的情况,以及解决方案...
- 5G 落地进入爆发期,是时候让毫米波登场了
- 读者诉苦:Redis 宕机,数据丢了,老板要辞退我
- ORACLE行转列通用过程(转)
- 7.剑指Offer --- 两个面试案例
- Windows 7 with SP1中英文原版MSDN下载汇总
- MISRA C_2012规则翻译、解读、示例
- 2019竞赛公开题库c语言,干货!全国电子设计大赛你必知的C语言知识
- win7如何通过电脑系统开启无线热点
- SAP SD初阶之VL10A为销售订单创建外向交货单
- portknocking(端口试探)简介
- RTMP直播推流(二)音频推流
- 信息系统典型的开发架构
- 偏向锁,轻量级锁,重量级锁的核心原理
- 已解决mybatis报错:Invalid bound statement (not found)
- openresty中应用murmurHash
- 核密度函数加权直方图的计算