c# - protobuf-net inheritance shows base class in .proto file -
i building runtime model protobuf-net in runtime using reflection without annotating classes need serialize.
some of classes need serialize use inheritance , of course want properties base class(es).
protobuf-net not crawl inheritance tree default need tell base classes. wrote little piece of code this:
public class inheritancetest { public static string createproto() { var model = protobuf.meta.runtimetypemodel.default; var type = typeof(subclass); if (null != type.basetype && type.basetype != typeof(object)) { var hierarchy = new list<type> { type }; var basetype = type.basetype; while (null != basetype) { if (basetype != typeof(object)) { hierarchy.add(basetype); } basetype = basetype.basetype; } hierarchy.reverse(); var metatype = model.add(hierarchy.first(), true); (int = 1; < hierarchy.count; i++) { model.add(hierarchy[i], true); metatype = metatype.addsubtype(i, hierarchy[i]); } } else { model.add(type, true); } var properties = type.getproperties(bindingflags.public | bindingflags.instance).orderby(p => p.name); var tagnumber = 1; foreach (var propertyinfo in properties) { model[type].add(tagnumber, propertyinfo.name); tagnumber++; } var schema = model.getschema(type, protosyntax.proto3); return schema; } } public class baseclass { public string stringproponbaseclass { get; set; } } public class subclass : baseclass { public string stringproponsubclass { get; set; } }
that produces .proto file this:
syntax = "proto3"; package protobufferserializertest; message baseclass { // following represent sub-types; @ 1 should have value optional subclass subclass = 1; } message subclass { string stringproponbaseclass = 1; string stringproponsubclass = 2; }
why baseclass included in .proto file? there no reason why needs bleed out public wire format.
is there way can tell runtime model not include in .proto flie?
br
because told to?
if change code to:
console.writeline("adding: " + hierarchy.first().name); var metatype = model.add(hierarchy.first(), true); (int = 1; < hierarchy.count; i++) { console.writeline("adding: " + hierarchy[i].name); model.add(hierarchy[i], true); console.writeline("adding sub type " + + " " + metatype.type.name); metatype = metatype.addsubtype(i, hierarchy[i]); }
we get:
adding: baseclass adding: subclass adding sub type 1 baseclass
so explicitly adding baseclass
contract type, , using addsubtype
explicitly connecting them in model. protobuf format (the google spec) does not handle inheritance, protobuf-net needs work within that, models inheritance via optional sub-objects, starting @ root - because that's way allows reliably deserialize baseclass
, have make sense. full description of see answer.
so: if actually intended support inheritance in serialization, expected , normal 2 types in .proto. if didn't intend support inheritance: *don't use addsubtype
. can add members need base type *directly onto subclass
:
public class inheritancetest { static void main() { console.writeline(createproto()); var obj = new subclass { stringproponbaseclass = "abc", stringproponsubclass = "def" }; var clone = serializer.deepclone(obj); console.writeline(clone.stringproponbaseclass); console.writeline(clone.stringproponsubclass); } public static string createproto() { var model = protobuf.meta.runtimetypemodel.default; var metatype = model.add(typeof(subclass), false); metatype.addfield(1, "stringproponsubclass"); metatype.addfield(2, "stringproponbaseclass"); var schema =model.getschema(typeof(subclass), protosyntax.proto3); return schema; } }
which outputs:
syntax = "proto3"; message subclass { string stringproponsubclass = 1; string stringproponbaseclass = 2; }
and
abc def
incidentally, approach allocating numbers sub-types in original code displays misunderstanding numbers valid or desirable. field numbers don't need different between different levels in hierarchy - in 5 level inheritance tree use 1
sub-type number if want. each sub-type number does need not conflict field numbers on same type. again, linked post goes more detail on this.
Comments
Post a Comment