Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
534 views
in Technique[技术] by (71.8m points)

c# - How to serialize generic inheritance class types with protobuf-net

I've got a rather complex model structure and I'm hoping I can implement the serialization with protobuf-net. I've written a couple of tests and most of them work absolutely fine, but some more complex generic class structures with inheritance on both the class type and the generic type don't work.

In the example below, the models don't have constructors, but I left them out to not overflow the post with information. Please assume that the parameterless constructors are implemented in all models. Also, I'm aware that some property names don't make sense, but it's a simplified prototype for a bigger project.

note: I know that this model is probably overcomplicated, but unfortunately I'm hugely stuck with it.

Models

[ProtoContract]
public class SaveData
{
    [ProtoMember(1)]
    public List<Entity> entities { get; set; }
}

[ProtoContract]
public abstract class Entity
{
    [ProtoMember(2)]
    public Guid ID { get; set; }
    [ProtoMember(3)]
    public string Name { get; set; }
}

[ProtoContract]
[ProtoInclude(910, typeof(SpecificEvent<SpecificEventArguments, SpecificEventContext>))]
public class Event<T, U> : Entity 
    where T : EventArguments
    where U : EventContext
{
    [ProtoMember(22)]
    public string EventName { get; set; }
    [ProtoMember(23)]
    public T EventArguments { get; set; }
    [ProtoMember(902)]
    public U EventContext { get; set; }
}

[ProtoContract]
[ProtoInclude(30, typeof(SpecificEventArguments))]
public class EventArguments
{
    [ProtoMember(24)]
    public int Argument { get; set; }
}

[ProtoContract]
[ProtoInclude(901, typeof(SpecificEventContext))]
public class EventContext
{
    [ProtoMember(900)]
    public string SomeContext { get; set; }
}

[ProtoContract]
public class SpecificEventArguments : EventArguments
{
    [ProtoMember(25)]
    public int SomeID { get; set; }
}

[ProtoContract]
public class SpecificEventContext : EventContext
{
}

[ProtoContract]
public class SpecificEvent<T, U> : Event<T, U>
    where T : SpecificEventArguments
    where U : SpecificEventContext
{
}

When I try to write some serialization logic in a simple main cmd-script, I can't seem to figure out why the serialization doesn't work.

Logic

static void Main(string[] args)
{
    SaveData saveData = new SaveData();
    SpecificEvent<SpecificEventArguments, SpecificEventContext> specificEvent = 
        new SpecificEvent<SpecificEventArguments, SpecificEventContext>(
            "specific", "event", 
            new SpecificEventArguments(1), 
            new SpecificEventContext());
    saveData.entities.Add(specificEvent);

    using (var file = File.Create("savedata.bin"))
    {
        Serializer.Serialize(file, saveData);
    }

    SaveData loaded = null;
    using (var file = File.OpenRead("savedata.bin"))
    {
        loaded = Serializer.Deserialize<SaveData>(file);
    }
}

I get the following exception:

System.InvalidOperationException: 'Unexpected sub-type: protobuf_net_test.Program+SpecificEvent`2[[protobuf_net_test.Program+SpecificEventArguments, protobuf-net-test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[protobuf_net_test.Program+SpecificEventContext, protobuf-net-test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'

Can anyone please explain me what I'm doing wrong? All help is really appreciated!!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...