.net - Protobuf-net - 如何使用 oneof

标签 .net grpc protobuf-net protobuf-net.grpc

我快速搜索了 Protobuf-netoneof 的用法,看起来是 supported as of v2.3.0 ,但我一生都找不到任何关于如何使用它的示例!

我的要求非常简单,也许这也可以用 [ProtoInclude] 来解决,但我不太确定这到底是如何工作的。我有以下类(class):

[ProtoContract]
public class ProgressUIMessage
{
    [ProtoMember(1)]
    public int Id {get; set;}

    [ProtoMember(2)]
    public object Message {get; set;}
}

其中消息可以是8种不同的已知类型之一。这些类型根本不互相继承,尽管可以更改代码,但所有类型没有任何共同点。

使用 Google.Protobuf 我希望做一些事情 similar to this ,其中我有一个名为 Instrument 的属性,它可以是上面示例中的两种类型之一,然后使用 InstrumentOneofCase 来确定给我的是哪种类型。但是如何在 Protobuf-net 中实现同样的效果呢?

编辑: 我将保留原来的问题,但也许更多人可以涉及的更好的问题是:你如何实现与 this MS example 相同的事情?在 Protobuf 网络中?无论是编写类本身还是确定参数最终是什么具体类型?

最佳答案

使用此方法的方法是从您引用的 MS 示例中获取消息,并通过 protogen 运行它以查看它的作用 - 我们可以在这里非常方便地执行此操作:https://protogen.marcgravell.com/ (请注意,我在文件顶部添加了 syntax = "proto3";,这在 MS 示例中被省略)。

这给我们带来了以下好处:

    [global::ProtoBuf.ProtoMember(2, Name = @"stock")]
    public Stock Stock
    {
        get => __pbn__instrument.Is(2) ? ((Stock)__pbn__instrument.Object) : default;
        set => __pbn__instrument = new global::ProtoBuf.DiscriminatedUnionObject(2, value);
    }
    public bool ShouldSerializeStock() => __pbn__instrument.Is(2);
    public void ResetStock() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__instrument, 2);

    private global::ProtoBuf.DiscriminatedUnionObject __pbn__instrument;

    [global::ProtoBuf.ProtoMember(3, Name = @"currency")]
    public Currency Currency
    {
        get => __pbn__instrument.Is(3) ? ((Currency)__pbn__instrument.Object) : default;
        set => __pbn__instrument = new global::ProtoBuf.DiscriminatedUnionObject(3, value);
    }
    public bool ShouldSerializeCurrency() => __pbn__instrument.Is(3);
    public void ResetCurrency() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__instrument, 3);

因此我们可以看到它基本上使用构建在DiscriminatedUnionObject 类型之上的条件序列化。实际上有一堆名为 DiscrimulatedUnion* 的相关类型 - 取决于您需要重叠的内容,但由于它们都是此处的消息类型:DiscrimulatedUnionObject 对我们有用。


还有一个可选的“oneof should use enum”选项(在:奇怪的是,“选项”下),如果启用,还会添加:

    public InstrumentOneofCase InstrumentCase => (InstrumentOneofCase)__pbn__instrument.Discriminator;

    public enum InstrumentOneofCase
    {
        None = 0,
        Stock = 2,
        Currency = 3,
    }

如果没有这个,您将必须使用 ShouldSerialize*() 方法来解决事件案例。

希望这能阐明如何将 oneof 与 protobuf-net 一起使用。

关于.net - Protobuf-net - 如何使用 oneof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69647655/

相关文章:

c# - Visual Studio 自动将我的一个属性更改为 null

c# - 无法弄清楚为什么 PHP 到 C# .NET 不会对称加密/解密

c# - 在 Dotnet Framework 4.8 客户端中使用 Core gRPC 服务器?

c# - ProtoBuf WCF 行为的配置错误

c# - 在 Protobuf-net 中序列化一个抽象列表

c# - await 不会按预期使用 StreamReader.ReadToEndAsync() 返回给调用者

c# - 随机存取存储器中的索引数据库

gradle - Gradle Protobuf任务未从依赖项中获取定义

grpc - 如何使用grpc在python服务器和php客户端之间进行通信?

c# - 在 Protobuf.NET 中序列化 List<object> (其中对象支持原语)?