序列化包含不可序列化成员的类

时间:2015-05-09 18:51:14

标签: c# serialization

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

实施例: 我有一个班级教学,有两个成员:

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

问题是,成员Op的类型在第三方库中,我不能使其可序列化。我尝试了BinaryFormatter和ProtoBuf,但都没有标记Op-member就失败了。

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

3 个答案:

答案 0 :(得分:2)

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

如果您使用[ProtoIgnore]Op的{​​{1}}属性,则可以使用ProtoBuf属性标记[NonSerialized]属性。

答案 1 :(得分:1)

一种方法是在Opcode上创建一个包装类,并在Instruction类中使用这个包装类的对象,以便在应用程序中进行序列化和其他目的。通过这种方式,您可以摆脱第三方库的任何限制。

答案 2 :(得分:0)

你可以:

public class GUI{
UpdateImage update;

 //more code

JLabel field;
SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                try {
                new UpdateImage(controller);
                } catch (Exception e) {

                    e.printStackTrace();
                }
            }
        });
}
field = update.getLabel( );


//more code

}

并禁用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; } } 的序列化。通过这种方式,您可以序列化操作码的OpName),然后您就可以对其进行反序列化。

使用string,您可以使用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内创建它的代理。