For example, there is a person class that stores the name of a person. (But this class will be replaced by another class person_ver2 in subsequent development ):
// + Using system. runtime. serialization
[Serializable, obsolete ("Please use the person_ver2 type")]
Class person: iserializable
{
Public string name {Get; set ;}
Public void getobjectdata (serializationinfo info, streamingcontext context)
{
Info. addvalue ("name", name );
}
/* Deserialization Code omitted */
}
Person_ver2 stores the name attribute of a person by its surname and name:
[Serializable]
Class person_ver2: iserializable
{
Public String firstname {Get; set ;}
Public String lastname {Get; set ;}
}
The problem is how to convert the serialized person-Class Object Data to the person_ver2 type in the deserialization process?
The serializationbinder class (in the system. runtime. serialization namespace) can help us meet this requirement.
By Rewriting the bindtotype method of serializationbinder, we can re-guide the type of the deserialization operation during the deserialization process. The type identifier is the complete path of the application Assembly name and type. Of course, the corresponding deserialization type must have operations to process other data of the guided type.
Therefore, the person_ver2 type should be defined as follows:
// New person class: person_ver2
[Serializable]
Class person_ver2: iserializable
{
Public String firstname {Get; set ;}
Public String lastname {Get; set ;}
// Deserialization
Protected person_ver2 (serializationinfo, streamingcontext context)
{
Try
{
Firstname = info. getstring ("firstname ");
Lastname = info. getstring ("lastname ");
}
Catch (serializationexception)
{
// If an error occurs (firstname and lastname do not exist in serializationinfo)
// It indicates the deserialization object data guided by the person class.
Console. writeline ("converting from person type to person_ver2 ");
// Deserialize the person class and convert the cost type
VaR names = info. getstring ("name"). Split ('');
Firstname = Names [0];
Lastname = Names [1];
}
}
Public override string tostring ()
{
Return string. Format ("Name: {0}-{1}", firstname, lastname );
}
// Serialization Code omitted
Public void getobjectdata (serializationinfo info, streamingcontext context)
{
Throw new notimplementedexception ();
}
}
Then, in the execution of serializationbinder, the type name of the application assembly is used to determine whether the type is person. If the type ID of person_ver2 is returned.
// + Using system. runtime. serialization
// Execution class of serializationbinder
Class conversionbinder: serializationbinder
{
Public override type bindtotype (string assemblyname, string typename)
{
// Filter the person type
// Determine whether it is of the person type. If it is of the person_ver2 type
VaR curassname = typeof (Program). Assembly. fullname;
VaR person1 = typeof (person). fullname;
String finaltype = typename;
If (assemblyname = curassname & typename = person1)
Finaltype = typeof (person_ver2). fullname;
Return type. GetType (finaltype + "," + assemblyname );
}
}
Finally, you can perform the conversion. Note that serializationbinder is set through the binder attribute of iformatter.
Main function code:
// + Using system. runtime. serialization
// + Using system. runtime. serialization. formatters. Binary
// + Using system. IO;
// Create a person object
VaR p1 = new person () {name = "Kevin Martin "};
Using (var ms = new memorystream ())
{
VaR BF = new binaryformatter ();
// Set the custom serializationbinder object
BF. Binder = new conversionbinder ();
// Serialize person
BF. serialize (MS, P1 );
Ms. Seek (0, seekorigin. Begin );
// Deserializes a person into person_ver2
VaR P2 = (person_ver2) BF. deserialize (MS );
// Output person_ver2
Console. writeline (p2.tostring ());
}
Output:
Convert from person type to person_ver2
Name: Kevin-Martin
OK. The deserialization person object successfully calls the deserialization constructor of person_ver2 and converts the person object to the person_ver2 object.