【问题标题】:How to generate struct with ProtoGen from proto file如何从 proto 文件中使用 ProtoGen 生成结构
【发布时间】:2025-11-27 08:50:01
【问题描述】:

我们一直在使用 protobuf-net ProtoGen 从 *.proto 文件生成 C# .cs 文件。我们想代替类来生成结构。例如

[DataContract]
public struct Entity1
{
    [ProtoMember(1)]
    public double Field1 { get; set; }

    [ProtoMember(2)]
    public string Field2 { get; set; }
}

我尝试使用 Serializer.GetProto 方法提取协议缓冲区,用于类和结构类型。看来,协议缓冲区(.proto)无法识别结构和类之间的区别。所以我暗示,这可能是 ProtoGen 中的一个参数,用于在从 .proto 生成的类/结构之间进行选择。该功能是否存在或者我如何解决从 *.proto 生成结构的问题?

【问题讨论】:

  • 为什么你特别需要struct
  • @Lloyd 在 .NET 中,与类相比,结构不会带来额外的运行时和内存开销。例如,考虑 SharpDX 中 3D 矢量的定义。它被声明为一个包含 3 个字段的结构,而不是一个类。部分原因是因为您希望向量列表是 blittable,但另一个原因是,如果将向量声明为类,则分配大量(例如一百万项)向量数组会产生难以置信的内存开销。

标签: c# .net protobuf-net


【解决方案1】:

目前,ProtoGen 只发出类;由于数据本质上是可变的,我会说这是合理的,但是 - 有两种选择:

  • 编辑csharp.xslt 以将class 替换为struct(或复制 csharp.xslt,并使用-t 参数告诉它使用副本)
  • “按原样”使用它,并明智地使用 ctrl+h(我知道技术含量低;但它会起作用)

【讨论】:

  • 这仍然应该在最新的 github 源上工作吗?尝试了一下,但我点击了throw new NotSupportedException("IExtensible is not supported in structs or classes with inheritance");
  • 好吧,没关系。删除结构类型上的 IExtensible 似乎工作正常。我决定手写 C# 代码而不是使用 protogen,因为我可以使用公共字段和结构而不是属性等。