Как сериализовать общие типы классов наследования с помощью protobuf-net

#c# #generics #inheritance #protobuf-net

#c# #общие #наследование #protobuf-net

Вопрос:

У меня довольно сложная структура модели, и я надеюсь, что смогу реализовать сериализацию с помощью protobuf-net. Я написал пару тестов, и большинство из них работают абсолютно нормально, но некоторые более сложные структуры общих классов с наследованием как по типу класса, так и по общему типу не работают.

В приведенном ниже примере модели не имеют конструкторов, но я оставил их, чтобы не переполнять сообщение информацией. Пожалуйста, предположите, что конструкторы без параметров реализованы во всех моделях. Кроме того, я знаю, что некоторые имена свойств не имеют смысла, но это упрощенный прототип для более крупного проекта.

примечание: Я знаю, что эта модель, вероятно, слишком сложна, но, к сожалению, я сильно застрял с ней.

Модели

 [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
{
}
 

Когда я пытаюсь написать некоторую логику сериализации в простом main cmd-скрипте, я не могу понять, почему сериализация не работает.

Логические

 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);
    }
}
 

Я получаю следующее исключение:

 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]]'
 

Может кто-нибудь, пожалуйста, объяснить мне, что я делаю не так? Вся помощь действительно ценится!!

Комментарии:

1. Основной причиной является отсутствие прото-включения в событии `2; не на ПК — вы пробовали добавить это включение? Или компилятор не разрешает это из-за общего ограничения? Его почти наверняка можно взломать, особенно во время выполнения с помощью обратных вызовов модели, но: Я сейчас занимаюсь рождественской вещью — на самом деле не кодирую в течение нескольких дней (я автор библиотеки, на случай, если это покажется ненужной информацией!) Также: какую версию библиотеки вы используете?

2. Прежде всего, спасибо за удивительно быстрый ответ, особенно в праздничный период. Я на самом деле забыл включить (без каламбура) эту строку, поэтому я добавил ее в исходное сообщение. К сожалению, он по-прежнему не работает и выдает мне ту же ошибку. О, и номер версии — V3.0.73 (последняя версия)

3. Кей, я попробую взглянуть, когда закончу с праздниками; спасибо за обновление