0

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 クラスは、Device クラスが存在するプロジェクトで参照する外部 dll にあります。

これはその内容です:

[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 を使用します。ご協力ありがとうございました!

4

1 に答える 1

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このデータをどこかに保存している場合、最善の策ではないかもしれません。それは…もろい。はるかに信頼性の高い一連のシリアライザーがあります。

于 2013-08-19T08:38:23.150 に答える