Почему я могу сериализовать Type [], только если он обернут в объект? - PullRequest
1 голос
/ 25 марта 2020

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

// Fails with 
// System.InvalidOperationException
// Type is not expected, and no contract can be inferred: System.RuntimeType
//   at ProtoBuf.Meta.TypeModel.ThrowUnexpectedType(Type type) in C:\Code\protobuf-net\src\protobuf-net\Meta\TypeModel.cs:line 1471
//   at ProtoBuf.Meta.TypeModel.TrySerializeAuxiliaryType(ProtoWriter writer, Type type, DataFormat format, Int32 tag, Object value, Boolean isInsideList, Object parentList) in C:\Code\protobuf-net\src\protobuf-net\Meta\TypeModel.cs:line 172
//   at ProtoBuf.Meta.TypeModel.SerializeCore(ProtoWriter writer, Object value) in C:\Code\protobuf-net\src\protobuf-net\Meta\TypeModel.cs:line 194
//   at ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value, SerializationContext context) in C:\Code\protobuf-net\src\protobuf-net\Meta\TypeModel.cs:line 222
//   at ProtoBuf.Serializer.Serialize[T](Stream destination, T instance) in C:\Code\protobuf-net\src\protobuf-net\Serializer.cs:line 93
//   at my bit of code

public static void SerializeMyClass()
{
    using (var ms = new MemoryStream())
    {
        Serializer.Serialize(ms, new[] {typeof(int)});
    }
}
// Works perfectly (and deserializes correctly too, not shown here for brevity)

[ProtoContract]
public class MyClass
{
    [ProtoMember(1)] public Type[] Types;
}

public static void SerializeMyClass()
{
    using (var ms = new MemoryStream())
    {
        Serializer.Serialize(ms, new MyClass {Types = new[] {typeof(int)}});
    }
}

Что я не понимаю? Можно ли сериализовать массив типов, не оборачивая их сначала, и если да, то что я должен делать по-другому?

Заранее спасибо!

1 Ответ

1 голос
/ 25 марта 2020

Здесь будет короткая версия: потому что Type имеет специальную обработку, и она никогда не тестировалась и не исправлялась в этом сценарии. Я согласен, что это странное и неожиданное поведение, и я исправил его в кодовой базе v3 в этом коммите . Это исправление не будет перенесено обратно в v2.

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

Однако! Я бы предостерег вас от сериализации Type слишком охотно; как вы можете видеть из полезной нагрузки в тестах, Type имеет неприятную особенность в том, что, поскольку он кодирует метаданные сборки, он может стать неуклюжим, если сборки меняются. И между. NET framework и. NET core, сборки меняются . Вы можете обойти это, подписавшись на событие DynamicTypeFormatting на модели типа, но ... это просто заставляет работать все больше и больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...