发生问题:
问题发生情况如下,有一个用于序列化的对象SerializeFileInfo,在A程序集中。后来为了写个小程序(暂且叫他App.exe),要求该程序不依赖于任何除.net以外的类库。为了不copy代码和统一管理,所以在该程序项目中将SerializeFileInfo这个类“添加为链接”。
这下问题来了。当时我用Test项目测试(引用了A.dll),序列、反序列化都测试通过了。后来用App.exe去反序列化Test生成的序列化文件时,却抛异常。然后试了多次,发现只要是反序列化本项目生成的序列化文件是可以的,反序列化其他项目生成的序列化文件就异常。比如用Test序列化,然后用App.exe反序列化,会抛异常“找不到A.dll程序集”。因为Test是引用了A.dll,但App.exe却并没引用任何其他dll。难道序列化还跟程序集的关系有关?想想不太可能啊,好诡异的问题。
解决问题:
调试异常代码是这句SerializeFileInfo[] array = new BinaryFormatter().Deserialize(stream) as SerializeFileInfo[]。array得到了一个null,再看Deserialize(stream)里有个异常“在分析完成之前就遇到流结尾。”这是怎么回事,为什么同项目反序列化可以,换个项目反序列化就抛这种异常?然后在网上查了半天跟Stream和Serialize的有关东西,折腾了半天,未果。
最后我建了一个B项目,同时引用了A.dll和App.exe,这时出现了一个红色波浪线提示,我才醒悟过来。罪魁祸首就是“添加为链接”!因为添加为链接后,在写代码时,命名空间.类名是一样的,再加上又在同一个解决方案中,让我误以为这是同一个类。虽然是同命名空间.类名,但因为在不同的程序集中,其实已变成了两个不同的类。我序列化A.dll中的SerializeFileInfo,却想反序列化成App.exe中的SerializeFileInfo,就出现了上面的问题。
总结:
还是自己的粗心造成的。如果遇到不同程序集,但同命令空间.类名的情况,可用extern alias,详见http://msdn.microsoft.com/zh-cn/library/ms173212(v=vs.80).aspx。因为我没深入研究过序列化的原理,所以想到了一个问题,如果是两个A.dll,不知道能否反序列化成功?我还未试过。。。