简体   繁体   中英

ProtoBuf doesn't deserialize an object with interface

I have a TCP socket, I want to send and receive objects using ProtoBuf. But I'm getting this error:

Exception thrown: 'System.InvalidOperationException' in protobuf-net.dll

Type is not expected, and no contract can be inferred: Server.Packet.IMsg

My Interface:

 public interface IMsg { }

One of the objects that I want to sent and received:

[ProtoContract]
public class PacketPerson : IMsg
{
    [ProtoMember(1)]
    public string Name{ get; set; }
    [ProtoMember(2)]
    public string Country { get; set; }
}

My socket is trying to deserialize after getting the full buffer:

 IMsg msg = Serialization.Desirialize(SocketMemoryStream);

Desirialize:

    public static IMsg Desirialize(MemoryStream ms) // socket buffer
    {
        ms.Position = 0;
        return Serializer.Deserialize<IMsg>(ms);
    }

yes, but I want to send multi-object and to identify them by using "Type type = packet.GetType();"Then use If statement "if (type == typeof(PacketPerson))"

My suggestion (speaking as the author):


[ProtoContract]
[ProtoInclude(1, typeof(PacketPerson))]
// future additional message types go here
class SomeMessageBase {}

[ProtoContract]
class PacketPerson : SomeMessageBase
{
    [ProtoMember(1)]
    public string Name{ get; set; }
    [ProtoMember(2)]
    public string Country { get; set; }
}

and deserialize/serialize <SomeMessageBase> . The library will deal with all the inheritence in the right way here. Behind the scenes, this will be implemented similarly to (in .proto terms):

message SomeMessageBase {
    oneof ActualType {
        PacketPerson = 1;
        // ...
    }
}
message PacketPerson {
    string Name = 1;
    string Country = 2;
}

You can now use either polymorphism or type testing for determining the actual type at runtime. The new switch syntax is especially useful:

SomeMessageBase obj = WhateverDeserialize();
switch(obj)
{
    case PacketPerson pp:
        // do something person-specific with pp
        break;
    case ...:
        // etc
        break;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM