Protobuf-net - 如何使用oneof
Protobuf-net - How to use oneof
我快速搜索了 oneof
在 Protobuf-net
中的用法,它似乎是 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;}
}
其中 Message
可以是 8 种不同的 已知 类型中的一种。这些类型根本不相互继承,虽然代码可以更改,但所有类型都没有共同点。
使用 Google.Protobuf
我希望做一些事情 similar to this,其中我有一个 属性 称为 Instrument
,它可以是上面示例中的两种类型之一然后使用 InstrumentOneofCase
找出给我的是哪种类型。但是我如何在 Protobuf-net
中实现同样的事情?
编辑:
我将保留最初的问题,但也许更多人可以联系到的一个更好的问题是:您将如何实现与 Protobuf-net 中的 this MS example 相同的事情?无论是在编写 class 本身方面,还是在确定参数最终是什么具体类型方面?
玩这个的方法是从你引用的 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
类型之上的条件序列化。实际上有一堆名为 DiscriminatedUnion*
的相关类型 - 取决于您需要重叠的内容,但由于它们在这里都是消息类型:DiscriminatedUnionObject
对我们有用。
还有一个可选的“oneof
应该使用枚举”选项(在:奇怪的是,“选项”下),如果启用,还会添加:
public InstrumentOneofCase InstrumentCase => (InstrumentOneofCase)__pbn__instrument.Discriminator;
public enum InstrumentOneofCase
{
None = 0,
Stock = 2,
Currency = 3,
}
否则,您将不得不使用 ShouldSerialize*()
方法来解决活动案例。
希望这能阐明 oneof
如何与 protobuf-net 一起使用。
我快速搜索了 oneof
在 Protobuf-net
中的用法,它似乎是 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;}
}
其中 Message
可以是 8 种不同的 已知 类型中的一种。这些类型根本不相互继承,虽然代码可以更改,但所有类型都没有共同点。
使用 Google.Protobuf
我希望做一些事情 similar to this,其中我有一个 属性 称为 Instrument
,它可以是上面示例中的两种类型之一然后使用 InstrumentOneofCase
找出给我的是哪种类型。但是我如何在 Protobuf-net
中实现同样的事情?
编辑: 我将保留最初的问题,但也许更多人可以联系到的一个更好的问题是:您将如何实现与 Protobuf-net 中的 this MS example 相同的事情?无论是在编写 class 本身方面,还是在确定参数最终是什么具体类型方面?
玩这个的方法是从你引用的 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
类型之上的条件序列化。实际上有一堆名为 DiscriminatedUnion*
的相关类型 - 取决于您需要重叠的内容,但由于它们在这里都是消息类型:DiscriminatedUnionObject
对我们有用。
还有一个可选的“oneof
应该使用枚举”选项(在:奇怪的是,“选项”下),如果启用,还会添加:
public InstrumentOneofCase InstrumentCase => (InstrumentOneofCase)__pbn__instrument.Discriminator;
public enum InstrumentOneofCase
{
None = 0,
Stock = 2,
Currency = 3,
}
否则,您将不得不使用 ShouldSerialize*()
方法来解决活动案例。
希望这能阐明 oneof
如何与 protobuf-net 一起使用。