当试图读取流的末尾时,没有无参数构造函数异常
本文关键字:参数 异常 构造函数 读取 | 更新日期: 2023-09-27 18:02:13
在过去的几个小时里,我一直在与异常'No parameterless constructor found for [type]'
作斗争。现在我创建了一个简单的单元测试,它应该反映我在应用程序中得到的内容,并且当我不执行stream.Position = 0
时,似乎会抛出此异常。
同样,当对象只是一个标准类(不是从抽象类派生的)时,我不会得到这个异常。
请看下面的代码:
-
按原样运行它-它会显示无法找到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的流在protobuf-net中是有效的;在protobuf-net中,所有的序列化都从DTO继承树的根类型开始,所以它会从Base
开始——直到它同意数据实际上包含Derived
,它才会相信你——并且会尝试使用Base
。所以这就是为什么#1扔。
显然,如果您将流留在末尾,则可用于反序列化的数据长度为零。这就是为什么#2通过了。
如果你删除继承,那么继承树的根是Derived
;这是一个根本性的变化,但在继承方面的不同之处在于,它不再试图在没有任何信息的情况下反序列化abstract
类型。所以这就是为什么#3修复了它(因为不好的原因)。