过去几个小时我一直在努力解决'No parameterless constructor found for [type]'
异常问题。现在我创建了一个简单的单元测试,它应该反映我在应用程序中的内容,而且当我不执行stream.Position = 0
时,似乎抛出了这个异常。
此外,当对象只是一个标准类(不是从抽象类派生)时,我不会得到这个异常。
请参阅以下代码:
按原样运行 - 它会断言没有为Base找到构造函数
取消注释stream.Position = 0并且没问题
再次注释该行,将Derived类更改为不从Base继承并取消注释该类中的唯一属性,运行它 - 它不会中断(但显然Name将为null)
有人可以解释为什么这种方式有效吗?为什么#1抛出(或为什么#3没有)以及为什么会出现此消息?
[Test]
public void CanSerialize_Derived()
{
var derived = new Derived() {Name = "ngf"};
var stream = new MemoryStream();
Serializer.Serialize(stream, derived);
//stream.Position = 0;
var deserializedInstance = Serializer.Deserialize<Derived>(stream);
}
[ProtoContract]
[ProtoInclude(9, typeof(Derived))]
public abstract class Base
{
[ProtoMember(1)]
public string Name { get; set; }
}
[ProtoContract]
public class Derived : Base
{
//[ProtoMember(1)]
//public string Name { get; set; }
}
答案 0 :(得分:5)
长度为零的流在protobuf-net中有效;在protobuf-net中,所有序列化都从该DTO继承树的根类型开始,因此它将在<{1}}处启动 - 直到它可以同意该数据实际上包含Base
,它不会相信你 - 并会尝试使用Derived
。所以这就是#1抛出的原因。
显然,如果将流保留在末尾,则可用于反序列化的数据长度为零。这就是#2通过的原因。
如果删除继承,则该继承树的根目录为Base
;这是一个根本性的突破性变化,但继承方面的差异在于它不再尝试在没有任何信息的情况下反序列化Derived
类型。所以这就是#3解决它的原因(出于不好的原因)。
这里的关键是继承实现为信息。除非有信息,否则它唯一假设的是对象属于继承树根的类型。