使用协议缓冲区模拟泛型
Posted
技术标签:
【中文标题】使用协议缓冲区模拟泛型【英文标题】:simulate generics with protocol buffer 【发布时间】:2014-09-21 09:17:01 【问题描述】:我有一个存储和操作一些实体的类。根据输入的数量,我可能无法将实体存储在内存中,因此我尝试使用协议缓冲区序列化要写入硬盘的对象。我正在使用 C# 和 protobuf-csharp-port。我知道protobuf-net 作为替代端口;到目前为止,我一直在使用第一个选项,但如果需要根据我的需要进行更改,我愿意进行更改。
要序列化的类的简化形式如下:
class Entity<T> where T: IComparable<T>
int id;
T metaData;
所以在编译时我对metaData
没有任何线索。谷歌搜索我注意到扩展是正确的路径(如google's page和this question所建议的那样);因此我为Entity
类定义Entity.proto
文件如下:
message Entity
required int32 id = 1 [default = 0];
extensions 2 to max;
我希望用户为T
提供他自己的.proto
文件,而无需访问或重新编译Entity.proto
。在这方面,我的问题是:
-
我需要更改
Entity.proto
吗?
T.proto
应该是什么?
如何在我的 C# 代码中访问 T
?
【问题讨论】:
【参考方案1】:使用该方案,任何扩展都将是非泛型Entity
的子值(不是子类)。这听起来不像是泛型,但最终存储(序列化)通常与实现完全不同(Entity<T>
等)。如果您可以在它们之间手动映射:很好。但这不是图书馆将提供的东西,AFAIK。
为了完整性,在 protobuf-net 术语中:使用 Entity<T>
完全没问题 - 它本质上认为每个(Entity<Foo>
、Entity<Bar>
等)都是完全独立的消息。 Protobuf-net 并没有受到 .proto 模式的极大推动(尽管为了完整性提供了代码生成工具)——它主要使用运行时元数据。
【讨论】:
如果我错了请纠正我:protobuf-net 支持泛型,然后我可以使用Entity<T>
编译我的库,它是序列化程序 (1)。使用该库时,T
用户还将提供它的序列化程序 (2)。最终,Entity<T>
的实例将使用 (1) 和 (2) 进行序列化。
@hamed 在使用 protobuf-net 时最常见,您根本不分发序列化程序:库会在需要时担心这一点。您分发序列化程序的主要时间是针对 AOT 设备
可能与 OOP 混合太多,但我完全糊涂了。 Entity
不知道 T
所以它不能序列化它。另一方面,T
不知道Entity
的数据结构,所以它也不能提供序列化。那我想知道Entity<Foo>
是怎么序列化的?
@Hamed 因为Entity<>
和T
都不负责序列化。 library 是 - 它看到的只是封闭的泛型类型Entity<Foo>
。坦率地说,它甚至都懒得去检查它是否是通用的——因为那根本不重要。
这解释了。之所以提出疑问,是因为我试图解释 .proto
方案中的所有内容,其中 Entity<T>
proto 在库构建时生成和编译,T
proto 生成并连接到它。以上是关于使用协议缓冲区模拟泛型的主要内容,如果未能解决你的问题,请参考以下文章
如何在 autoconf/automake 中使用协议缓冲区?