Созданный RuntimeTypeModel завершается ошибкой при десериализации сложного объекта - PullRequest
1 голос
/ 11 октября 2011

Я хотел использовать версию protocolbuf .net без атрибутов, с RuntimeTypeModel, созданным через определенный код Это работало довольно хорошо, пока я не попал в случай, который был извлечен в случае ниже. Ссылочная версия библиотеки protobuf-net: 2.0.0.447. Что не так с созданием этой модели? Любые подсказки?

public class ProtoBufFailingTest
{
    public abstract class Message
    {
    }

    public class SomeMessage : Message
    {
        public readonly Descriptor Desc;

        public SomeMessage(Descriptor desc)
        {
            Desc = desc;
        }
    }

    public struct Descriptor
    {
        public readonly Event EventData;

        public Descriptor(Event eventData)
        {
            EventData = eventData;
        }
    }

    public abstract class Event
    {
    }

    public class SomeEvent : Event
    {
        public int SomeField;
    }

    [Test]
    public void FailingTest( )
    {
        var model = TypeModel.Create();

        // message hierarchy
        {
            var messages = model.Add(typeof(Message), true);
            messages.AddSubType(1, typeof(SomeMessage));
            model[typeof(SomeMessage)].UseConstructor = false;
        }

        // events hierarchy
        {
            var events = model.Add(typeof (Event), true);
            events.AddSubType(1, typeof (SomeEvent));
            model[typeof (SomeEvent)].UseConstructor = false;
        }

        // descriptor
        var eventDescriptorModel = model.Add(typeof(Descriptor), true);
        eventDescriptorModel.UseConstructor = false;

        var typeModel = model.Compile();

        const PrefixStyle prefixStyle = PrefixStyle.Base128;
        const int testValue = 5;
        using (var ms = new MemoryStream())
        {

            typeModel.SerializeWithLengthPrefix(ms, new SomeMessage(new Descriptor(new SomeEvent { SomeField = testValue })), null, prefixStyle, 0);

            ms.Seek(0, SeekOrigin.Begin);

            // fails here
            var message = (SomeMessage)typeModel.DeserializeWithLengthPrefix(ms, null, typeof(Message), prefixStyle, 0);

            Assert.AreEqual(testValue, ((SomeEvent)message.Desc.EventData).SomeField);
        }
    }
}

1 Ответ

0 голосов
/ 12 октября 2011

Очень просто; в библиотеке есть (была) ошибка, издающая

initobj {type}
stloc.0

когда очевидно (кашель) для типа значения Descriptor он должен был излучать

ldloca.s 0
initobj {type}

Я разверну это, как только проверю, я ничего не дестабилизировал.

...