【问题标题】:protobuf-net: ProtoException in serializing and deserializing nullable enum with length prefixprotobuf-net:在序列化和反序列化具有长度前缀的可空枚举时出现 ProtoException
【发布时间】:2020-08-07 12:57:03
【问题描述】:

这段代码重现了这个问题:

Type Resolver(int fieldNumber)
{
    return typeof(ConsoleColor?);
}

var stream = new MemoryStream();
ConsoleColor? obj = ConsoleColor.Green;
Serializer.NonGeneric.SerializeWithLengthPrefix(stream, obj, PrefixStyle.Base128, 1);

stream.Position = 0;
Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, Resolver, out var dd);
//EXCEPTION!!!

我只是在序列化一个可为空的枚举值。但是当我尝试反序列化时,出现以下异常:

ProtoBuf.ProtoException:线型无效;这通常意味着您在没有截断或设置长度的情况下覆盖了文件;见https://stackoverflow.com/q/2152978/23354'

我做错了什么?有没有办法解决或解决这个问题?我正在使用 protobuf-net 库的 2.4.6 版本。 (无法迁移到 3.x,因为我被 .Net Framework 4.0 卡住了)。

【问题讨论】:

    标签: c# .net-4.0 protobuf-net


    【解决方案1】:

    当您将Nullable<T> 传递给采用object 的API 时,它被装箱,而Nullable<T> 的装箱规则很特殊:它装箱到任一 em> 一个普通的null,或者一盒T,而不是一盒T?;换句话说:objectnever 包含可为空的值类型。因此,从图书馆的角度来看,您发送的是ConsoleColor,而不是ConsoleColor?,所以:

    Type Resolver(int fieldNumber)
    {
        return typeof(ConsoleColor);
    }
    

    不过,附带说明一下:解析器 API 非常特定且利基市场,并且通常有更好的方法来做事。如果你能告诉我你想要实现什么,我可能会提供更多指导。

    (我正在尝试考虑是否存在曾经解析器可以有意义地为某些T返回typeof(Nullable<T>)的场景 - 我们可能可能有库只是解开可空对象本身,或者提出更有意义的消息)

    【讨论】:

    • 感谢马克!是的,我现在确实看到了这个问题。实际上我有一个 RPC 库,它会自动为方法参数生成序列化程序。例如,在调用int Sum(int a, int b) 期间,库序列化参数a(字段编号为1)和b(字段编号为2)并通过线路发送。在接收端,它执行相反的操作来获取参数并调用函数调用。当我使用 SomeEnum? 作为参数时,我被卡住了。
    • 但我还是不明白为什么int? 有效而SomeEnum? 无效?
    猜你喜欢
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    相关资源
    最近更新 更多