2015-05-09 107 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

相關問題