我快速搜索了 Protobuf-net
中 oneof
的用法,看起来是 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/