具有泛型类型的protobuf-net继承

时间:2016-05-06 20:12:22

标签: generics inheritance serialization protobuf-net

在使用更复杂的层次结构(包括泛型和继承)时,尝试使用protobuf-net执行反序列化时遇到了一些问题。

动态定义类型层次结构的方法是什么?

有趣的是序列化工作正常,但反序列化失败,消息出现异常:"无法为以下内容准备序列化程序:Serialization.command.ICommand"

请参阅我使用的代码:

    [ProtoContract]
public abstract class AbstractEntity
{

    public AbstractEntity()
    {

    }
    protected AbstractEntity(int integer)
    {
        this.integer = integer;
    }

    private int noSerializable = 0;
    [ProtoMember(1)]
    public int NoSerializable { get { return noSerializable; }
        set { noSerializable=value; }
    }
}


[ProtoContract]
public class Entity:AbstractEntity
{
    public Entity() : base()
    {

    }
    public Entity(int integer) : base(integer)
    {
    }
    [ProtoMember(2)]
    public String Name { get; set; }
    [ProtoMember(3)]
    public String Surname { get; set; }
    [ProtoMember(4)]
    public int Age { get; set; }
}

[ProtoContract]
public interface ICommand
{
    void Execute();
}

[ProtoContract]
public abstract class AbstractCommand: ICommand
{
    public  abstract void someAbstractMet();
    public  void Execute()
    {

    }
}

[ProtoContract]
public  class AbstractEntityCommand<T>:AbstractCommand where T:AbstractEntity
{

    [ProtoMember(1)]
    public T Entity { set; get; }

    public AbstractEntityCommand()
    {

    } 
    public AbstractEntityCommand(T entity)
    {
        Entity = entity;
    }

    public override void someAbstractMet()
    {

    }
}

[ProtoContract]
public class UpdateEntityCommand<T>:AbstractEntityCommand<T> where T:AbstractEntity
{
    public UpdateEntityCommand()
    {

    } 

    public UpdateEntityCommand(T entity):base(entity)
    {

    } 
    public override void someAbstractMet()
    {

    }

}


class Program
{
    static void Main(string[] args)
    {


        var entity = new Entity(4);
       Console.WriteLine("Using Protobuf");
        //first define dinamicaly the hierarchy -  see ProtoInclude attribute
        RuntimeTypeModel.Default.Add(typeof (AbstractEntity), true).AddSubType(7, typeof (Entity));
        AbstractEntity absEnt = entity;
        bites = absEnt.ProtoBufSerialize();

        thirdEntity = (Entity)bites.ProtoBufDeserialize<AbstractEntity>();
        Console.WriteLine("Name=" + thirdEntity.Name + "   Surname=" + thirdEntity.Surname + "  Age=" + thirdEntity.Age + "   integer=" + thirdEntity.TheInt + " No serializable field = " + thirdEntity.NoSerializable);

       // Console.ReadKey();

        Console.WriteLine("Test for generics");

        RuntimeTypeModel.Default.Add(typeof(ICommand), true).AddSubType(70, typeof(AbstractCommand));

        RuntimeTypeModel.Default.Add(typeof(ICommand), true).AddSubType(80, typeof(AbstractEntityCommand<>));
        RuntimeTypeModel.Default.Add(typeof(ICommand), true).AddSubType(90, typeof(UpdateEntityCommand<>));

        ICommand genCommand = new UpdateEntityCommand<Entity>(entity);


       bites =  genCommand.ProtoBufSerialize();
        var concreteCmd = bites.ProtoBufDeserialize<UpdateEntityCommand<Entity>>();
        var unknownCmd = bites.ProtoBufDeserialize<ICommand>();

        Console.ReadKey();
    }

一切正常,直到我尝试反序列化ICommand。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

泛型不是问题,protobuf-net支持那些。问题是您有一个接口作为根对象。虽然将接口序列化为成员是完全正确的,但接口不可能充当根对象。

因此

bites.ProtoBufDeserialize<ICommand>();

抛出异常。