我认为protobuf不支持继承,因为我在另一端使用protoc-c,所以我也不想使用任何扩展。但是,我坚持使用依赖于继承的C#模型:
class Header {
public int version { get; set; }
}
class Message : Header {
public String message { get; set; }
}
我试图将继承切换为有线格式的封装:
[ProtoContract]
class Header {
[ProtoMember(1)]
public int version { get; set; }
}
[ProtoContract]
class Message : Header {
[ProtoMember(1)]
public Header Header { get { return this; } set { } }
[ProtoMember(2)]
public String Message { get; set; }
}
然后我收到“Unexpected sub-type”错误,提示我: Why I have to use [ProtoInclude]?
我觉得我的情况与上述问题的情况不同,所以我想再次询问我的具体案例,我试图在内部继承,如果没有ProtoInclude,这是不可能的吗?
如果没有,我将如何在v2中完成?
-----编辑------
我在C(使用protobuf-c)方面的原型文件是这样的:
message Header {
optional int32 version = 1;
}
message Message {
optional Header header = 1;
optional string message = 2;
}
我不想把Message放在Header中,而且我不想要继承线上的功能。这种格式使我能够轻松地将内容添加到Header消息中,而无需更改消息消息。
答案 0 :(得分:0)
使用编辑:否,不直接支持该场景 - protobuf-net非常了解继承,并且不太容易忽略它。这似乎是一个不寻常的情况,我不是绝望添加它,我认为return this;
getter和no-op setter会引起额外的下游并发症(不是bug,因为它不是“期望支持那个”,这可能很难纠正。
我建议使用与您想要表示的结构类似的模型。如果这不是直接,则可以使用代理。以下工作并保留您的预期线结构和现有类型继承:
using ProtoBuf;
using ProtoBuf.Meta;
// DTO model - maps directly to the wire layout
[ProtoContract]
class HeaderDto
{
[ProtoMember(1)]
public int Version { get; set; }
}
[ProtoContract]
class MessageDto
{
[ProtoMember(1)]
public HeaderDto Header { get { return header;}}
private readonly HeaderDto header = new HeaderDto();
[ProtoMember(2)]
public string Message { get; set; }
// the operators (implicit or explicit) are used to map between the
// primary type (Message) and the surrogate type (MessageDto)
public static implicit operator Message(MessageDto value)
{
return value == null ? null : new Message {
version = value.Header.Version, message = value.Message };
}
public static implicit operator MessageDto(Message value)
{
return value == null ? null : new MessageDto {
Message = value.message, Header = { Version = value.version } };
}
}
// domain model
class Header
{
public int version { get; set; }
}
class Message : Header
{
public string message { get; set; }
}
// example
static class Program
{
static void Main()
{
// configure the surrogate
RuntimeTypeModel.Default.Add(typeof(Message), false)
.SetSurrogate(typeof(MessageDto));
Message msg = new Message { version = 1, message = "abc" };
var obj = Serializer.DeepClone(msg);
}
}