Я использую версию 2 ProtoBuf-net, и в настоящее время я получаю сообщение об ошибке «Невозможно определить элемент: A»
Можно ли создать модель времени выполнения для Protobuf-net, когда мы используем ClassOfType ? Если да, может ли кто-нибудь определить, что мне не хватает в приведенном ниже коде?
btw: этот запрос смоделирован из Десериализовать неизвестный тип с помощью protobuf-net Я мог бы получить версию этого очень хорошо ... но они используют абстрактный базовый класс, а не универсальный класс Т.
ЭТО РАБОЧИЙ ПРИМЕР (вещи, которые не работали, удаляются).
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<SomeDerived>();
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<SomeBase>();
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<SomeDerived>), true); // BM_SD
model.Add(typeof(Container<SomeBase>), 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<SomeDerived>)model.DeserializeWithLengthPrefix(
ms
, null
, typeof(Container<SomeDerived>), PrefixStyle.Base128, 0);
var o2 = (Container<SomeBase>)model.DeserializeWithLengthPrefix(
ms
, null
, typeof(Container<SomeBase>), PrefixStyle.Base128, 0);
}
}
[ProtoContract]
public class Container<T> : 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<SomeDerived>)model.DeserializeWithLengthPrefix(...)
также может быть реализован так
model.DeserializeWithLengthPrefix<Container<SomeDerived>>(...):
Кстати: я начинаю копаться в реализации protobuf-net и начинаю замечать некоторые интересные методы, подобные этому. Что-то, к чему можно вернуться позже, я думаю:
public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType);
Обсуждение:
когда я увидел способ, которым вы можете десериализовать абстрактный тип базы в приведенной выше ссылке, я подумал: да, это ближе к тому, что мыслят Можем ли мы сначала десериализовать в открытый универсальный контейнер <>, а затем привести более конкретно, если нам нужно в разных сборках. Может быть, я немного запутался здесь.
Вы можете думать об этом в терминах Tupple . Или вариация, например, Tupple >. Это ничем не отличается от List . У меня есть некоторые TreeTypeThings , но мне не нужно их сериализовать / десериализовать (пока).
У меня работала неуниверсальная последовательность, так что это не остановка показа. Моя первая реализация может быть более эффективной. Я думаю, что я могу добиться большего успеха с существующими функциями protobuf-net.
Мне нравится более чистый способ работы с этими идеями. Хотя я могу добраться до того же пункта назначения вручную, Generics делает возможными другие вещи.
re: уточнение
вызывающий может определить все заранее. (кстати: вы заставили меня задуматься о сценарии только во время выполнения, но нет, мне это не нужно).