BinaryFormatter 和反序列化复杂对象

发布于 2024-10-17 16:13:29 字数 1673 浏览 7 评论 0原文

无法反序列化以下对象图。当在 BinaryFormmater 上调用反序列化方法时,会发生该异常: System.Runtime.Serialization.SerializationException:

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

C 上有两个构造函数,我认为问题可能是:当序列化 Binaryformatter 使用参数构造函数和反序列化过程时,它需要一个无参数构造函数。有黑客/解决方案吗? Objects :

  [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

Can not deserialize following object graph. That Exception occurs when deserialize method called on BinaryFormmater:
System.Runtime.Serialization.SerializationException :

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

There're two constructor on C. and I think the problem may be : While serialization Binaryformatter using the paramatered one and on deserialization process, it needs a parameterless one. Is there a hack / solution?
Objects :

  [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));
        }
    }

// Serialization success

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

// Deserialization fails

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

The calls are at the same environment, same thread, same method

        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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心碎无痕… 2024-10-24 16:13:29

我怀疑您只需要为 C 提供一个反序列化构造函数,因为字典实现了 ISerialized:

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

checked (passes):

 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
     }
 }

I suspect you just need to provide a deserialization constructor to C, since dictionary implements ISerializable:

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

checked (passes):

 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
     }
 }
原来分手还会想你 2024-10-24 16:13:29

当您按如下方式实现类 C 时,您的序列化将会成功:

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

    // implement interface ...
}

问题是 Dictionary 派生类的序列化。

Your serialization will succeed when you implement class C as following:

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

    // implement interface ...
}

The problem is the serialization of the Dictionary derived class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文