2015-05-09 106 views
1

是否有序列化包含不可序列化成员的类的可能性?包含不可序列化成员的序列化类

实施例: 我有一个类指令,它有两个构件:

public class Instruction 
{ 
    public OpCode Op { get; set; } 
    public object Operand { get; set; } 
} 

的问题是,该元件的类型op是在第三方库,我不能使它序列化。我尝试了BinaryFormatter和ProtoBuf,但都没有标记Op成员失败。

任何人都知道序列化我的对象的解决方案吗?

回答

1

显然,如果某个类的一部分不是可序列化的,则不能序列化该部分,但可以忽略它(并且在反序列化时给出一些默认值,可能值为null)。

可以使用[ProtoIgnore]属性,如果你使用的是ProtoBuf,或BinaryFormatter[NonSerialized]的属性标记的Op财产。

+0

但是当我需要该成员以备后用时,该怎么办? – user4653488

+0

那么,你不能序列化不可序列化的东西。如果不对这些类进行逆向工程,并且了解如何强制进行序列化,那么没有什么可以做的。也许'OpCode'使用本地资源? –

1

一种方法是在Opcode上创建包装类,并在指令类中使用此包装类的对象用于序列化和其他目的。这样,您可以摆脱与第三方库的任何限制。

0

,你可以:

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; } 
} 

和禁用序列化Op。通过这种方式,您可以序列化操作代码(string)的Name,然后您就可以反序列化它。

随着BinaryFormatter您可以使用ISerializable接口和手动序列化:使用

[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); 
    } 
} 

例子:

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); 
} 

如果Operand可以的东西,是不能直接序列化,您可以创建它在GetObjectData内的替代品。

+0

这是OpCode的一种可能的方式,但它不适用于对象吗?我的意思是,操作数可以有多种类型。 – user4653488

+0

@user请参阅扩展响应。令人遗憾的是,protobuf不支持在“对象”内部序列化原始类型('int','short',...) – xanatos

相关问题