protobuf-net - 为什么以下琐碎的 C# 代码会引发有关缺少默认构造函数的 ProtoException?
问题描述
这是代码:
using System.Diagnostics;
using System.IO;
using ProtoBuf;
namespace ProtoBufTest
{
[ProtoContract]
[ProtoInclude(13, typeof(BuildEvent))]
public abstract class Event
{
[ProtoMember(1)]
public int NodeId { get; set; }
}
[ProtoContract]
public class BuildEvent : Event
{
}
public class Program
{
static void Main(string[] args)
{
var ms = new MemoryStream();
Serializer.SerializeWithLengthPrefix<object>(ms, new BuildEvent(), PrefixStyle.Base128);
Debug.WriteLine(ms.Position);
ms.Position = 0;
var ev = Serializer.DeserializeWithLengthPrefix<BuildEvent>(ms, PrefixStyle.Base128);
Debug.WriteLine(ev.ToString());
}
}
}
我正在使用 protobuf-net 2.4.0。运行此代码会引发以下异常:
Unhandled Exception: ProtoBuf.ProtoException: No parameterless constructor found for ProtoBufTest.Event
at ProtoBuf.Meta.TypeModel.ThrowCannotCreateInstance(Type type)
at proto_4(Object , ProtoReader )
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source)
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source)
at ProtoBuf.Meta.TypeModel.DeserializeWithLengthPrefix(Stream source, Object value, Type type, PrefixStyle style, Int32 expectedField, TypeResolver resolver, Int64& bytesRead, Boolean& haveObject, SerializationContext context)
at ProtoBuf.Serializer.DeserializeWithLengthPrefix[T](Stream source, PrefixStyle style, Int32 fieldNumber)
at ProtoBuf.Serializer.DeserializeWithLengthPrefix[T](Stream source, PrefixStyle style)
at ProtoBufTest.Program.Main(String[] args) in C:\Work\ProtoBufTest\ProtoBufTest\Program.cs:line 30
解决方案
这里的使用<object>
不正确;这就是说“我知道类型 - 类型是object
”。如果您没有对泛型友好的场景,则应使用非泛型 API - 请参阅Serializer.NonGeneric.*
或使用RuntimeTypeModel.Default.*
; 然后这将Type
通过对象获得。
我会考虑是否应该让<object>
自动切换到非泛型模式。
推荐阅读
- python-3.x - 基于索引的两个多级数据帧的乘法和加法
- java - java - 如何在不使用包的情况下识别给定路径是Java中的文件还是目录?
- crystal-lang - 无法从水晶游戏中访问模型
- python - 在 conda 环境中管理 python 版本
- python - 与 pandas 和 GNU Parallel 并行将数据导入 MySQL
- excel - 为什么VBA根据值是否在数组中计算不同?
- amazon-web-services - 在 AWS 中选择数据存储类型
- php - 如何从公共文件夹 Laravel 中获取文件列表
- php - Prestashop 1.7 - 访问一般首选项或管理时出现错误 500
- java - Apache-poi:想要遍历一个excel列并总结下一列中存在的相应值