#c# #protobuf-net
#c# #protobuf-net
Вопрос:
Я хотел использовать protocolbuf .net версии без атрибутов, с RuntimeTypeModel, созданной с помощью определенного кода. Это работало довольно хорошо, пока я не попал в дело, которое было извлечено в случае ниже. Версия библиотеки protobuf-net, на которую ссылается protobuf, равна 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. Извините, я как-то пропустил это вчера. Я далеко от своего компьютера, но подготовлю ответ на это позже, когда вернусь.
2. Жду вашего ответа. Будьте осторожны!
3. хм, да, это глупо; посмотрите на это повторно; это ошибка IL emit (переполнение стека), так что в тесте нет ничего плохого (за исключением того, что он не добавляет
.SomeField
кSomeEvent
‘sMetaType
)4. Теперь это исправлено в r450 ( code.google.com/p/protobuf-net/downloads )
5. Это работает как шарм. Спасибо за самую быструю помощь.
Ответ №1:
Очень просто; в библиотеке есть (была) ошибка, выдающая
initobj {type}
stloc.0
когда очевидно (кашель) для типа значения Descriptor
, он должен был выдавать
ldloca.s 0
initobj {type}
Я разверну это, как только проверю, что я ничего не дестабилизировал.