No it doesn't make sense, and you can' t deserialize a type to be another type that I know about.
Deserialize under other class name, or change class name in serialized document c#
I c# would like to change the name of a class that is being persisted through serialization/deserialization (using a binary formatter). If I simply refactor the name to another name, the desirialization of the file won't load (nor did I expect this).
Is there a way to tell the deserializer to load the class under another class-name, so that I can change the name of the class but still keep the old (and big!) file. Or can I serialize using another class name.
Does the question make sense?
2 answers
Sort by: Most helpful
-
-
Timon Yang-MSFT 9,591 Reputation points
2020-12-21T06:19:08.257+00:00 Please take a look at this example, it seems to meet your requirements.
class App { [STAThread] static void Main() { Serialize(); Deserialize(); } static void Serialize() { FileStream fs = new FileStream("DataFile.dat", FileMode.Create); try { BinaryFormatter formatter = new BinaryFormatter(); Version1Type obj = new Version1Type(); obj.x = 123; formatter.Serialize(fs, obj); } catch (SerializationException e) { Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } static void Deserialize() { Version2Type obj = null; FileStream fs = new FileStream("DataFile.dat", FileMode.Open); try { BinaryFormatter formatter = new BinaryFormatter(); formatter.Binder = new Version1ToVersion2DeserializationBinder(); obj = (Version2Type)formatter.Deserialize(fs); } catch (SerializationException e) { Console.WriteLine("Failed to deserialize. Reason: " + e.Message); throw; } finally { fs.Close(); } Console.WriteLine("Type of object deserialized: " + obj.GetType()); Console.WriteLine("x = {0}, name = {1}", obj.x, obj.name); } } [Serializable] class Version1Type { public Int32 x; } [Serializable] class Version2Type : ISerializable { public Int32 x; public String name; [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("x", x); info.AddValue("name", name); } [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] private Version2Type(SerializationInfo info, StreamingContext context) { x = info.GetInt32("x"); try { name = info.GetString("name"); } catch (SerializationException) { name = "Reasonable default value"; } } } sealed class Version1ToVersion2DeserializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { Type typeToDeserialize = null; String assemVer1 = Assembly.GetExecutingAssembly().FullName; String typeVer1 = "Version1Type"; if (assemblyName == assemVer1 && typeName == typeVer1) { typeName = "Version2Type"; } typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName)); return typeToDeserialize; } }
The code comes from a Microsoft documentation, and I deleted the comments to make it look more condensed.
If you want to know more, you can check the original document.
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.