I am deserializing protocol buffer data using Protobuf-NET and am dealing with multiple Proto files that are identical but have slightly different extensions. Basically each Proto feed is 99% identical and then has 1 or 2 fields different from each other provided as extensions for each. So I ended up with multiple Proto classes that are 99% identical.
Logically I want to add inheritance to generated C# proto files in order to avoid 99% of redundant code parsing each feed. The problem is that I am getting the following error upon deserialization:
System.NotSupportedException
HResult=0x80131515
Message=IExtensible is not supported in structs or classes with inheritance
Source=protobuf-net
StackTrace:
at ProtoBuf.Serializers.TypeSerializer..ctor(TypeModel model, Type forType, Int32[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, Boolean isRootType, Boolean useConstructor, CallbackSet callbacks, Type constructType, MethodInfo factory) in C:\code\protobuf-net\src\protobuf-net\Serializers\TypeSerializer.cs:line 97
at ProtoBuf.Meta.MetaType.BuildSerializer() in C:\code\protobuf-net\src\protobuf-net\Meta\MetaType.cs:line 480
at ProtoBuf.Meta.MetaType.get_Serializer() in C:\code\protobuf-net\src\protobuf-net\Meta\MetaType.cs:line 372
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in C:\code\protobuf-net\src\protobuf-net\Meta\RuntimeTypeModel.cs:line 802
at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) in C:\code\protobuf-net\src\protobuf-net\Meta\TypeModel.cs:line 718
at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in C:\code\protobuf-net\src\protobuf-net\Meta\TypeModel.cs:line 590
at ProtoBuf.Serializer.Deserialize[T](Stream source) in C:\code\protobuf-net\src\protobuf-net\Serializer.cs:line 68
So it would seem that this scenario is not supported. Now what's not clear is if this applies to IExtensible usage in the Base class or the derived class. Base class must remain extensible since I'm applying multiple extensions, but the extension / derived classes do not.
I have code similar to the one below taken from this post. Now before anyone labels it as "Duplicate" - it is not because my question is completely different. While it's OP is asking about the purpose of IExtensible and consequences of not implementing it, I am asking about any possible workaround or solution for the above described use case.
[ProtoBuf.ProtoInclude(1000, typeof(DerivedClass))]
public partial class BaseClass : ProtoBuf.IExtensible
{
...
private IExtension extensionObject;
IExtension IExtensible.GetExtensionObject(bool createIfMissing)
{
return Extensible.GetExtensionObject(ref extensionObject, createIfMissing);
}
}
public partial class DerivedClass : BaseClass, ProtoBuf.IExtensible
{
...
private IExtension extensionObject;
IExtension IExtensible.GetExtensionObject(bool createIfMissing)
{
return Extensible.GetExtensionObject(ref extensionObject, createIfMissing);
}
}
var baseObject = new MyClass { ... };
DerivedClass derivedObject;
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, baseObject); // throws runtime exception
stream.Seek(0, SeekOrigin.Begin);
derivedObject = Serializer.Deserialize<DerivedClass>(stream);
}
Question: how can I achieve inheritance with above described scenario? I am open to modifying the derived class, any other work around you could suggest, or even using another .NET Protobuf library.
The fundamental problem here is that there is a collision:
oneof
at each decision pointI have thought about extending the API to make it track the extensions against the logical type (which would map to the message), but this is complex and would take me time to add.
Most other protobuf tools do not support inheritance at all, so I doubt you'd find that a viable workaround.
So: that's why it isn't there; that doesn't really.givr you a workaround, sorry. The only "fix" here is "take the time to implement the complexity of per-type extension storage and retrieval"
User contributions licensed under CC BY-SA 3.0