protobuf-net 在使用 .ToProto() 时将 List<T> 转换为 List_T 类

Posted

技术标签:

【中文标题】protobuf-net 在使用 .ToProto() 时将 List<T> 转换为 List_T 类【英文标题】:protobuf-net converts List<T> to List_T class when using .ToProto() 【发布时间】:2020-02-13 23:06:30 【问题描述】:

我需要获取一个实现protobuf-net 的C# 类库,并将它们转换为.proto 文件,这些文件需要使用protoc 转换为.py 文件。我知道.ToProto() 函数可以很好地执行此操作,但是在从 .proto 转换为 .py 文件时遇到了涉及集合和泛型的问题。例如,当尝试序列化 DateTimes 列表时,我收到以下错误 X.proto:64:13. "List_TimeSpan" is not defined. 因为这在序列化到 protobuf 文件时没有引起问题,所以当时我不知道这种情况。

我目前在这个项目中使用proto-buf.net 2.3.2;这是我的其他一些工作已经完成的版本,我知道这可以通过版本升级来解决。我只是不确定这是否是我迄今为止所做的挖掘的答案。如果我还缺少其他东西,我将非常感谢任何可以帮助我的方法。

【问题讨论】:

【参考方案1】:

如果我们考虑:

[ProtoContract]
public class Foo 
    [ProtoMember(12)]
    public List<DateTime> Times  get;  = new List<DateTime>();

然后在 v2.3.2(问题中提到的版本)和 v2.4.4(当前默认版本)中生成 GetProto&lt;T&gt;()

syntax = "proto2";
import "protobuf-net/bcl.proto"; // schema for protobuf-net's handling of core .NET types

message Foo 
   repeated .bcl.DateTime Times = 12;

所以表面上,应该已经没问题了。如果您正在做一些更奇特的事情(也许使用字典值中的列表?),我很乐意提供帮助,但我需要更多关于您在做什么的线索。发布一些 C# 来展示你所看到的东西将是一个很好的起点。


请注意,当 protobuf-net 刚出现时,对于类似日期/时间的值并没有约定的传输格式,所以 protobuf-net 编造了一些东西,但事实证明 不是方便适合跨平台工作;以下是一项重大更改(它数据兼容),但如果可能,我强烈推荐 Google 稍后添加的众所周知的格式:

[ProtoContract]
public class Foo 
    [ProtoMember(12, DataFormat = DataFormat.WellKnown)]
    public List<DateTime> Times  get;  = new List<DateTime>();

生成:

syntax = "proto2";
import "google/protobuf/timestamp.proto";

message Foo 
   repeated .google.protobuf.Timestamp Times = 12;

【讨论】:

非常感谢您的帮助,马克!我目前没有做任何超级疯狂的事情(字典中没有列表);我们做的最糟糕的是列表和字典,它们可能正在实现其他 protobufs

以上是关于protobuf-net 在使用 .ToProto() 时将 List<T> 转换为 List_T 类的主要内容,如果未能解决你的问题,请参考以下文章

使用 protobuf-net.Grpc 的客户端回调

关于在 C# 中使用 Protobuf-Net

如何使用 protobuf-net 处理 .proto 文件

使用带有标志枚举的 ProtoBuf-Net 时出错

如何在 VB.NET 中使用 protobuf-net 添加枚举?

protobuf-net 使用索引属性时如何避免崩溃