Att via referens är alltid att föredra som det föreslogs ovan, men då man inte har tillgång till assemblen (.dll el. .exe) så kan man ange en SerializationBinder till din *Formatter klass.
Då behöver programmet som deserialiserar enbart veta vad de olika fälten heter och dess typ. (i detta exempel iaf)
Lite långt men jag postar de två 'projekten' iaf.
Först programmet för att serialisera en klass med ISerializable interfacet.
using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Security.Permissions;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
/// C# / NET 2.0 / AUTOGENERATED 24 jul 2006
namespace Zoomware.Examples.Serialization
{
// this program serialize data to test.dat
class TestClassA
{
[STAThread]
static void Main ( string [ ] args )
{
MyCustomSerializableClassA classA = new MyCustomSerializableClassA ( );
classA.n = 456;
try
{
using ( FileStream stream = new FileStream ( @d:\test.dat, FileMode.Create ) )
{
BinaryFormatter formatter = new BinaryFormatter ( );
formatter.Serialize ( stream, classA );
}
}
catch ( SerializationException e )
{
Console.WriteLine ( e.Message );
}
}
}
[Serializable]
public class MyCustomSerializableClassA : ISerializable
{
public MyCustomSerializableClassA ( )
{
}
protected MyCustomSerializableClassA ( SerializationInfo info, StreamingContext context )
{
n = info.GetInt32 ( "myint" );
s = info.GetString ( "mystring" );
}
[SecurityPermissionAttribute ( SecurityAction.Demand, SerializationFormatter = true )]
public void GetObjectData ( SerializationInfo info, StreamingContext context )
{
info.AddValue ( "myint", n );
info.AddValue ( "mystring", s );
}
public int n = 123;
private string s = "abc";
}
}
Och, sedan deserialiseringen med användandet av en egen SerializationBinder.
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
/// C# / NET 2.0 / AUTOGENERATED 24 jul 2006
namespace Zoomware.Examples.Serialization
{
// this program deserialize data from test.dat without knowing the base class it was serialized from
class TestClassB
{
[STAThread]
static void Main ( string [ ] args )
{
try
{
using ( FileStream stream = new FileStream ( @d:\test.dat, FileMode.Open ) )
{
BinaryFormatter formatter = new BinaryFormatter ( );
formatter.Binder = new TypeAToTypeB ( );
MyCustomSerializableClassB classB = new MyCustomSerializableClassB ( );
Console.WriteLine ( "new class B: {0}, {1}", classB.n, classB.s );
classB = ( MyCustomSerializableClassB ) formatter.Deserialize ( stream );
Console.WriteLine ( "deserialized class B: {0}, {1}", classB.n, classB.s );
}
}
catch ( Exception e )
{
Console.WriteLine ( e.Message );
}
}
}
[Serializable]
public class MyCustomSerializableClassB : ISerializable
{
public MyCustomSerializableClassB ( )
{
}
protected MyCustomSerializableClassB ( SerializationInfo info, StreamingContext context )
{
n = info.GetInt32 ( "myint" );
s = info.GetString ( "mystring" );
}
[SecurityPermissionAttribute ( SecurityAction.Demand, SerializationFormatter = true )]
public void GetObjectData ( SerializationInfo info, StreamingContext context )
{
info.AddValue ( "myint", n );
info.AddValue ( "mystring", s );
}
public int n = 0;
public string s = string.Empty;
public string s2 = "another string that does not exists in the other class so there is an obvious difference";
}
public class TypeAToTypeB : System.Runtime.Serialization.SerializationBinder
{
public override Type BindToType ( string assemblyName, string typeName )
{
return typeof ( MyCustomSerializableClassB );
}
}
}
EDIT: fixade return raden i BindToType så att den använde typeof på ett bättre sätt.