一个关于反序列化的小问题

  

  大家都知道,我们具有三种定义可序列化类型的方式:在类型上应用SerializableAttribute特性;应用DataContractAttribute/DataMemberAttribute特性和实现ISerializable接口。当你通过继承一个现有的类来定义你需要被序列化的类,如果这个父类实现了ISerializable接口,如果定义不当,就会出现反序列化的问题。而且这个我们可能经常都不注意。

  一、问题重现

  首先,我想自定义一个字典类型MyDictionary,其Key和Value的类型分别为String和Object。最简单的方式莫过于直接继承Dictionarystring, object。为了让MyDictionary对象可序列化,我们在类型上面应用了SerializableAttribute特性。MyDictionary定义如下:

  1:[Serializable]

  2:publicclassMyDictionary:Dictionarystring,object

  3:{

  4:}

  然后我通过下面的代码对MyDictionary对象进行序列化和反序列化,我直接采用的序列化器为BinaryFormatter。

  1:staticvoidMain(string[]args)

  2:{

  3:vardictionary=newMyDictionary();

  4:dictionary.Add(001,Foo);

  5:dictionary.Add(002,Bar);

  6:dictionary.Add(003,Baz);

  7:

  8:using(MemoryStreamstream=newMemoryStream())

  9:{

  10:varformatter=newBinaryFormatter();

  11:formatter.Serialize(stream,dictionary);

  12:stream.Seek(0,0);

  13:dictionary=(MyDictionary)formatter.Deserialize(stream);

  14:}

  15:

  16:foreach(varitemindictionary)

  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:publicclassMyDictionary:Dictionarystring,object

  3:{

  4:publicMyDictionary(){}

  5:protectedMyDictionary(SerializationInfoinfo,StreamingContextcontext):base(info,context){}

  6:}

  从新运行我们的程序,你就会得到想要的输出结果:

  1:001:Foo

  2:002:Bar

  3:003:Baz

  如果一个类型实现了ISerializable接口(DictionaryTKey, TValue就实现了这个接口),你就应该定义如上一个构造函数。这算是一个约定,但是当你继承某个类型的时候,你往往会忘记这个约定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值