24

次のオブジェクト グラフをデシリアライズできません。その例外は、BinaryFormmater: System.Runtime.Serialization.SerializationException で呼び出された deserialize メソッドで発生します。

The constructor to deserialize an object of type 'C' was not found.

C.には2つのコンストラクターがあり、問題は次のようになると思います:パラメーター付きのものと逆シリアル化プロセスを使用するシリアライゼーション Binaryformatter では、パラメーターなしのコンストラクターが必要です。ハック/解決策はありますか? オブジェクト:

  [Serializable]
    public class A
    {
        B b;
        C c;

        public int ID { get; set; }

        public A()
        {
        }

        public A(B b)
        {
            this.b = b;
        }

        public A(C c)
        {
            this.c = c;
        }
    }
    [Serializable]
    public class B
    {

    }
    [Serializable]
    public class C : Dictionary<int, A>
    {
        public C()
        {

        }

        public C(List<A> list)
        {
            list.ForEach(p => this.Add(p.ID, p));
        }
    }

// シリアライズ成功

    byte[] result;
    using (var stream =new MemoryStream())
    {
        new BinaryFormatter ().Serialize (stream, source);
        stream.Flush ();
        result = stream.ToArray ();
    }
    return result;

// デシリアライズ失敗

    object result = null;
    using (var stream = new MemoryStream(buffer))
    {
        result = new BinaryFormatter ().Deserialize (stream);
    }
    return result;

呼び出しは同じ環境、同じスレッド、同じメソッドにあります

        List<A> alist = new List<A>()
        {
            new A {ID = 1},
            new A {ID = 2}
        };

        C c = new C(alist);
        var fetched = Serialize (c); // success
        var obj = Deserialize(fetched); // failes
4

2 に答える 2

37

Cディクショナリが実装しているため、デシリアライゼーション コンストラクタを に提供するだけでよいと思いますISerializable

protected C(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {}

チェック済み (合格):

 static void Main() {
     C c = new C();
     c.Add(123, new A { ID = 456});
     using(var ms = new MemoryStream()) {
         var ser = new BinaryFormatter();
         ser.Serialize(ms, c);
         ms.Position = 0;
         C clone = (C)ser.Deserialize(ms);
         Console.WriteLine(clone.Count); // writes 1
         Console.WriteLine(clone[123].ID); // writes 456
     }
 }
于 2011-02-16T14:00:01.013 に答える
1

次のようにクラス C を実装すると、シリアル化が成功します。

[Serializable]
public class C : IDictionary<int,A>
{
    private Dictionary<int,A> _inner = new Dictionary<int,A>;

    // implement interface ...
}

問題は Dictionary 派生クラスのシリアル化です。

于 2011-02-16T13:56:14.467 に答える