对象序列化问题(c#)

时间:2013-08-19 08:24:15

标签: c# serialization

亲爱的Stack Overflow社区, 我以为我永远不会问这个问题,但显然序列化或我对它的使用有问题。

我有一个我需要序列化的课程:

[Serializable]
public class Device : ISerializable, IDisposable
{
   public delegate void ListChangedEventHandler(object sender, ListChangedEventArgs e);
   public string Name { get; set; }
   public string Description { get; set; }
   public string IPAddress { get; set; }

   [Browsable(false)]
   public ThreadSafeBindingList<Item> Items { get; set; }

    [Browsable(false)]
    public MibEntity AssociatedMibEntity { get; set; }

    //methods etc.
}

一点解释:

ThreadSafeBindingList继承自System.ComponentModel.BindingList MibEntity是一类SharpSNMP库(http://sharpsnmplib.codeplex.com/

问题: 当我尝试反序列化对象时,MibEntity始终为null。其他房产很好。 MibEntity类位于外部dll中,我在Device类所在的项目中引用它。

这是其内容:

[Serializable]
public class MibEntity 
{
    public MibEntity()
    {
        Children = new List<MibEntity>(); 
    } 

    [Browsable(false)]
    public List<MibEntity> Children { get; set; }

    [Browsable(true)]
    [Category("General")]
    public string OID { get; set; }

    private string _name;
    [Browsable(true)]
    [Category("General")]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    [Browsable(true)]
    public string Description { get; set; }

    [Browsable(false)]
    public int Value { get; set; }


    [Browsable(true)]
    public AccessType AccessType { get; set; } //this is enum from SharpSNMP library

    [Browsable(true)]
    public Status Status { get; set; } //this is enum from same assembly as this class

    [Browsable(true)]
    public string Syntax { get; set; }

    [Browsable(true)]
    public bool IsTableEntry { get; set; }

    [Browsable(true)]
    public IDefinition IDefinition { get; set; } //this is interface from SharpSNMP library
}

我使用BinaryFormatter进行序列化和反序列化。 谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

这总是意味着您在自定义ISerializable实施中犯了错误;以下工作正常:

protected Device(SerializationInfo info, StreamingContext context)
{
    Name = info.GetString("Name");
    //...
    AssociatedMibEntity = (MibEntity)info.GetValue(
        "AssociatedMibEntity", typeof(MibEntity)); 
}
void ISerializable.GetObjectData(
    SerializationInfo info, StreamingContext context)
{
    info.AddValue("Name", Name);
    //...
    info.AddValue("AssociatedMibEntity", AssociatedMibEntity);
}

验证:

using (var ms = new MemoryStream())
{
    var bf = new BinaryFormatter();
    bf.Serialize(ms, new Device {
        AssociatedMibEntity = new MibEntity { Name = "Foo"}});
    ms.Position = 0;
    var clone = (Device)bf.Deserialize(ms);
    Console.WriteLine(clone.AssociatedMibEntity.Name); // Foo
}

但是,除非有充分理由实施ISerializable,否则只需完全删除您的ISerializable实施,您就可以获得更好的服务 - 并指出这将是一个突破更改(如果执行此操作,任何现有数据都不会正确反序列化。)

[Serializable]
public class Device : IDisposable // <=== no ISerializable; also removed
                                  // GetObjectData and custom .ctor

另外:如果你将这些数据存储在任何地方,我常见的咆哮:BinaryFormatter可能不是你最好的选择。它是...... 脆弱。有一系列更可靠的序列化器。