ProtoBuf-net AsReference 需要 Activator.CreateInstance 中的公共构造函数吗?
在处理我的 2 个看起来像这样的类(最小)时
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using ProtoBuf;
namespace Sandbox
{
public partial class Form1 : Form
{
public Form1()
{
Family family = new Family();
Child child1 = new Child(1);
Child child2 = new Child(2);
Parent parent = new Parent(new List<Child>() { child1, child2 });
family.Add(parent);
string file = "sandbox.txt";
try { File.Delete(file); } catch { }
using (var fs = File.OpenWrite(file)) { Serializer.Serialize(fs, family); }
using (var fs = File.OpenRead(file)) { family = Serializer.Deserialize<Family>(fs); }
System.Diagnostics.Debug.Assert(family != null, "1. Expect family not null, but not the case.");
}
}
[ProtoContract()]
public class Child
{
[ProtoMember(1, AsReference = true)]
internal Parent Parent;
private Child() { }
public Child(int i) { }
}
[ProtoContract()]
public class Parent
{
[ProtoMember(1)]
protected List<Child> m_Children;
/// <summary>
/// ProtoBuf deserialization constructor (fails here)
/// </summary>
private Parent() { m_Children = new List<Child>(); }
public Parent(List<Child> children)
{
m_Children = children;
m_Children.ForEach(x => x.Parent = this);
}
}
[ProtoContract()]
public class Family
{
[ProtoMember(1)]
protected List<Parent> m_Parents;
public void Add(Parent parent)
{
m_Parents.Add(parent);
}
public Family()
{
m_Parents = new List<Parent>();
}
}
}
,在反序列化过程中,我遇到了异常“没有为此对象定义无参数构造函数”。用于在 ProtoBuf.BclHelper 附近创建 Parent 对象
case FieldObject:
// ...
value = ((options & NetObjectOptions.UseConstructor) == 0) ? BclHelpers.GetUninitializedObject(type) : Activator.CreateInstance(type);
然后,当我将默认构造函数 Parent() 更改为 public 时,异常消失了。
知道我可能忽略了在这种情况下 AsReference 的正确用法吗?
赏金: 虽然 Marc 花时间解决这个问题,但我需要一个明确的解决方案来在这种情况下使用 protobuf-net,通过 protobuf-net 属性、方法或其他技巧来解决。否则我将不得不完全放弃使用 protobuf-net。感谢您的任何帮助。
While working on 2 of my classes that looks like this (minimal)
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using ProtoBuf;
namespace Sandbox
{
public partial class Form1 : Form
{
public Form1()
{
Family family = new Family();
Child child1 = new Child(1);
Child child2 = new Child(2);
Parent parent = new Parent(new List<Child>() { child1, child2 });
family.Add(parent);
string file = "sandbox.txt";
try { File.Delete(file); } catch { }
using (var fs = File.OpenWrite(file)) { Serializer.Serialize(fs, family); }
using (var fs = File.OpenRead(file)) { family = Serializer.Deserialize<Family>(fs); }
System.Diagnostics.Debug.Assert(family != null, "1. Expect family not null, but not the case.");
}
}
[ProtoContract()]
public class Child
{
[ProtoMember(1, AsReference = true)]
internal Parent Parent;
private Child() { }
public Child(int i) { }
}
[ProtoContract()]
public class Parent
{
[ProtoMember(1)]
protected List<Child> m_Children;
/// <summary>
/// ProtoBuf deserialization constructor (fails here)
/// </summary>
private Parent() { m_Children = new List<Child>(); }
public Parent(List<Child> children)
{
m_Children = children;
m_Children.ForEach(x => x.Parent = this);
}
}
[ProtoContract()]
public class Family
{
[ProtoMember(1)]
protected List<Parent> m_Parents;
public void Add(Parent parent)
{
m_Parents.Add(parent);
}
public Family()
{
m_Parents = new List<Parent>();
}
}
}
During deserialization, I encounter the exception "No parameterless constructor defined for this object." for creating the Parent object in ProtoBuf.BclHelper near
case FieldObject:
// ...
value = ((options & NetObjectOptions.UseConstructor) == 0) ? BclHelpers.GetUninitializedObject(type) : Activator.CreateInstance(type);
Then when I changed the default constructor Parent() to public, the exception goes away.
Any idea what I may have overlooked is the correct usage for AsRerference in this case?
BOUNTY:
While Marc takes his time to fix the issue, I would require a definitive solution to use protobuf-net in this situation, working around either by protobuf-net attributes, methods or other tricks. Otherwise I will have to abandon the use of protobuf-net altogether. Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信你可以这样做来解决这个问题:
}
I believe you can do this to fix this problem:
}
当您反序列化
Parent
时,您需要公共无参数构造函数。因此,失败的最小测试用例是:创建具有非空m_Parent
的Child
,将其序列化并反序列化结果。When you deserialize
Parent
, you need the public parameterless constructor. So, your minimal test-case that fails is: createChild
that has non-nullm_Parent
, serialize it and deserialize the result.