C#反序列化已经移动或重命名为一类 [英] C# Deserialize a class which has moved or been renamed

查看:131
本文介绍了C#反序列化已经移动或重命名为一类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在一个名为AssemblyA装配有一个名为MyClass的级,并将其序列化到使用.net的BinaryFormatter的文件。然后移动MyClass的的code到名为AssemblyB汇编,并尝试反序列化,我得到了下面的System.TypeLoadException异常的文件:

If I have a class named "MyClass" in an assembly named "AssemblyA" and serialize it to a file using .NET's BinaryFormatter. Then move the code of "MyClass" into an assembly named "AssemblyB" and try to deserialize the file I get the following "System.TypeLoadException" exception:

未能加载从装配式'AssemblyA.MyClass'AssemblyA,版本= 1.0.0.0,文化=中立,公钥=空'。

Could not load type 'AssemblyA.MyClass' from assembly 'AssemblyA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

有没有办法为我指示该类已移至AssemblyB?通过某种属性?或者是有可能修改序列化的文件作为pre-preprocessing一步改变从AssemblyA.MyClass所有引用AssemblyB.MyClass?最后,如​​果没有这些选择都是可能的,是有可能绕过试图deserialise这个类,并继续反正deserialising数据的休息吗?

Is there any way for me to indicate that the class has been moved to AssemblyB? Via an attribute of some sort? Or is it possible to modify the serialised file as a pre-preprocessing step to change all references from AssemblyA.MyClass to AssemblyB.MyClass? Finally, if neither of those options are possible, is it possible to bypass trying to deserialise this class and continue deserialising the rest of the data anyway?

推荐答案

如果您移动它,然后添加到它现在居住DLL的引用,并使用<一个href=\"http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.typeforwardedtoattribute.aspx\"相对=nofollow> TypeForwardedToAttribute

If you have moved it, then add a reference to the dll where it now resides, and use TypeForwardedToAttribute:

[assembly:TypeForwardedTo(typeof(TheType))]

这将是足以让一些请求(包括的BinaryFormatter IIRC)在寻找一种可以找到它在新的装配。然而,IIRC它仅适用于最外层的类型(不嵌套类型,以及可能不是仿制药),你可以不用给它改名/改变了命名空间/等。

This will be enough for some requests (including BinaryFormatter IIRC) looking for a type to find it in the new assembly. However, IIRC it only works for outermost types (not nested types, and probably not generics), and you can't have renamed it / changed the namespace / etc.

更名为tricker ... 的BinaryFormatter 是出了名的脆性这样的事情。国际海事组织,它仅适用于序列2紧耦合系统之间的瞬态数据(例如,在相同的处理之间的两个应用程序域取值交换;用于存储时,或系统之间这可能不同步,也可以是一个噩梦。

Renaming is tricker... BinaryFormatter is notoriously brittle about such things. IMO, it is only suitable for serializing transient data between two tightly coupled systems (for example, exchange between two AppDomains in the same process; when used for storage, or between systems that might get out of sync, it can be a nightmare.

这可能是太晚了,但我会建议使用基于合同的序列化(而不是基于类型的序列化);任何的XmlSerializer 的DataContractSerializer 的(只要你使用 [DataContract] / [数据成员] 属性)等,如果你想快速的二进制,protobuf网将做好(和可以连接到<$ C $中C> ISerializable的如果需要)。

It may be too late, but I would recommend using a contract-based serializer (rather than a type-based serializer); any of XmlSerializer, DataContractSerializer (as long as you use the [DataContract]/[DataMember] attributes), etc. Of if you want fast binary, protobuf-net would do a good job (and can hook into ISerializable if you need).

这可能是值得考虑的另一个概念是系列化的代理人,但毕竟是比较辛苦。但IIRC这使您可以创建的类型控制 - 但你需要做的很多的工作吧。

Another concept that might be worth looking at is serialization surrogates, but that is relatively hard. But IIRC this gives you the control over the type that is created - but you need to do a lot of the work for it.

这篇关于C#反序列化已经移动或重命名为一类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆