开发者

Expand protobuf message with subclass

开发者 https://www.devze.com 2023-03-15 21:49 出处:网络
I have two classes that I would like to transform to protobuf messages: [ProtoContract] class ClassA {开发者_JAVA技巧

I have two classes that I would like to transform to protobuf messages:

[ProtoContract]
class ClassA {开发者_JAVA技巧
    [ProtoMember(1)]
    public int b;
    [ProtoMember(2)]
    public int c;
}

[ProtoContract]
class ClassD : ClassA
{
    [ProtoMember(3)]
    public int e;
    [ProtoMember(4)]
    public int f;
}

What I am trying to achieve is a serialization of ClassA containing b and c. And when serializing ClassD i will get b, c, e and f.

Is this possible, or what kind of approach should I use? I'm trying to avoid nested messages.

Using my approach I get a problem when serializing a ClassD object.

ClassD d = new ClassD();
Serialize.Serialize<ClassA>(stream, d);
Serialize.Serialize<ClassD>(stream, d);

In both attempts above the serialized data only contain the properties in ClassD and none from ClassA. I would expect at least none of the properties in ClassD to be serialized in the first case and I would like all, both from ClassA and ClassD to be serialized in the second case.

How would I approach this problem?


It looks like this works in v2 without inheritance:

    var model = TypeModel.Create();
    model.Add(typeof(ClassA), false).Add("b", "c");
    model.Add(typeof(ClassD), false).Add("b", "c", "e", "f");

    var a = new ClassA { b = 1, c = 2 };
    var aClone = (ClassA)model.DeepClone(a);
    Debug.Assert(aClone.b == 1);
    Debug.Assert(aClone.c == 2);

    var d = new ClassD { b = 1, c = 2, e = 3, f = 4};
    var dClone = (ClassD)model.DeepClone(d);
    Debug.Assert(dClone.b == 1);
    Debug.Assert(dClone.c == 2);
    Debug.Assert(dClone.e == 3);
    Debug.Assert(dClone.f == 4);

These will each be flat models, not nested. At the moment this would need explicit setup (as above), as it isn't part of how it builds the model by default - but as a corollary you don't need attributes here:

class ClassA
{
    public int b;
    public int c;
}
class ClassD : ClassA
{
    public int e;
    public int f;
}


Sure:

[ProtoContract, ProtoInclude(3, typeof(ClassD))]
class ClassA {...}

The "3" can be anything as long as it doesn't clash with anythig else from ClassA.

This will appear as a nested message on the wire, but automatically. If this is expressly not what you want, then let me know.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号