Разрешено ли в модели ProtoBuf-net во время выполнения?

Я использую версию 2 ProtoBuf-net, и в настоящее время я получаю сообщение об ошибке «Невозможно определить член: A»

Можно ли создать рабочую модель для Protobuf-net когда мы используем ClassOfType ? Если да, может ли кто-нибудь заметить, что мне не хватает в приведенном ниже коде?

кстати: этот запрос смоделирован на основе Десериализация неизвестного типа с помощью protobuf-net Я мог бы получить версию этого отлично ... но они используют абстрактный базовый класс, а не общий класс T.

ЭТО РАБОЧИЙ ПРИМЕР (все, что не работало, удаляется).

using System;
using System.IO;
using NUnit.Framework;
using ProtoBuf;
using ProtoBuf.Meta;

namespace ProtoBufTestA2
{
    [TestFixture]
    public class Tester
    {
        [Test]
        public void TestMsgBaseCreateModel()
        {
            var BM_SD = new Container();

            using (var o = BM_SD) {
                o.prop1 = 42;
                o.payload = new SomeDerived();
                using (var d = o.payload) {
                    d.SomeBaseProp = -42;
                    d.SomeDerivedProp = 62;
                }
            }

            var BM_SB = new Container();
            using (var o = BM_SB) {
                o.prop1 = 42;
                o.payload = new SomeBase();
                using (var d = o.payload) {
                    d.SomeBaseProp = 84;
                }
            }
            var model = TypeModel.Create();

            model.Add(typeof(Container), true);  // BM_SD
            model.Add(typeof(Container), true);  // BM_SB
            model.Add(typeof(SomeBase), true); // SB
            model.Add(typeof(SomeDerived), true);  // SD
            model[typeof(SomeBase)].AddSubType(50, typeof(SomeDerived)); // SD

            var ms = new MemoryStream();

            model.SerializeWithLengthPrefix(ms, BM_SD, BM_SD.GetType(), ProtoBuf.PrefixStyle.Base128, 0);

            model.SerializeWithLengthPrefix(ms, BM_SB, BM_SB.GetType(), ProtoBuf.PrefixStyle.Base128, 0);
            ms.Position = 0;
            var o1 = (Container)model.DeserializeWithLengthPrefix(
                ms
                , null
                , typeof(Container), PrefixStyle.Base128, 0);
            var o2 = (Container)model.DeserializeWithLengthPrefix(
                ms
                , null
                , typeof(Container), PrefixStyle.Base128, 0);
        }
    }

    [ProtoContract]
    public class Container : IDisposable
    {
        [ProtoMember(1)]
        public int prop1 { get; set; }

        [ProtoMember(2)]
        public T payload { get; set; }

        public void Dispose() { }
    }

    [ProtoContract]
    public class AnotherDerived : SomeDerived, IDisposable
    {
        [ProtoMember(1)]
        public int AnotherDerivedProp { get; set; }
        public override void Dispose() { }
    }

    [ProtoContract]
    public class SomeDerived : SomeBase, IDisposable
    {
        [ProtoMember(1)]
        public int SomeDerivedProp { get; set; }

        public override void Dispose() { }
    }

    [ProtoContract]
    public class SomeBase : IDisposable
    {
        [ProtoMember(1)]
        public int SomeBaseProp { get; set; }

        public virtual void Dispose() { }
    }

    [ProtoContract]
    public class NotInvolved : IDisposable
    {
        [ProtoMember(1)]
        public int NotInvolvedProp { get; set; }
        public void Dispose() { }
    }

    [ProtoContract]
    public class AlsoNotInvolved : IDisposable
    {
        [ProtoMember(1)]
        public int AlsoNotInvolvedProp { get; set; }
        public void Dispose() { }
    }
}

Запрос

Это второстепенно, но Было бы неплохо, если бы

  (Container)model.DeserializeWithLengthPrefix(...) 

можно было реализовать так же

  model.DeserializeWithLengthPrefix>(...):

кстати: я начинаю копаться в реализации protobuf-net и начинаю замечать некоторые интересные методы, подобные этому. Думаю, кое-что, к чему я вернусь позже:

  public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType);

Обсуждение:

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

Вы можете думать об этом в терминах Tupple . Или вариант вроде Tupple >, может быть. Это не сильно отличается от List . Есть и некоторые TreeTypeThings , которые у меня тоже есть, но мне не нужно их сериализовать / десериализовать (пока).

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

Мне нравится более чистый общий способ работы с этими идеями. Хотя я могу добраться до того же пункта назначения вручную, с помощью Generics возможны другие вещи.

re: разъяснение

все может быть определено заранее вызывающим. (кстати: вы заставили меня задуматься о сценарии времени выполнения, но нет, мне это не нужно).

6
задан Community 23 May 2017 в 12:04
поделиться