You could:
public class Instruction
{
public OpCode Op { get; set; }
public string OpString
{
get
{
return Op.Name;
}
set
{
Op = (OpCode)typeof(OpCodes).GetField(value, BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase).GetValue(null);
}
}
public object Operand { get; set; }
}
and disable serialization for Op. In this way you would serialize the Name of the op code (a string), and you would then be able to deserialize it.
With BinaryFormatter you could use the ISerializable interface and manually serialize:
[Serializable]
public class Instruction : ISerializable
{
public OpCode Op { get; set; }
public object Operand { get; set; }
public Instruction()
{
}
public Instruction(SerializationInfo info, StreamingContext context)
{
Op = (OpCode)typeof(OpCodes).GetField(info.GetString("Op"), BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase).GetValue(null);
Operand = info.GetValue("Operand", typeof(object));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Op", Op.Name);
info.AddValue("Operand", Operand);
}
}
Example of use:
var ins1 = new Instruction { Op = OpCodes.Add, Operand = (short)5 };
var ins2 = new Instruction { Op = OpCodes.Sub, Operand = 5.0 };
byte[] bytes;
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, ins1);
bf.Serialize(ms, ins2);
bytes = ms.ToArray();
}
Instruction ins3, ins4;
using (var ms = new MemoryStream(bytes))
{
var bf = new BinaryFormatter();
ins3 = (Instruction)bf.Deserialize(ms);
ins4 = (Instruction)bf.Deserialize(ms);
}
If Operand can be something that isn't directly serializable, you can then create a surrogate of it inside the the GetObjectData.