C# Deserialize a class which has moved or been renamed

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-20 13:59:16

问题


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:

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

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?


回答1:


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

[assembly:TypeForwardedTo(typeof(TheType))]

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.

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.

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).

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.



来源:https://stackoverflow.com/questions/1465079/c-sharp-deserialize-a-class-which-has-moved-or-been-renamed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!