protobuf- net: ProtoException при сериализации и десериализации обнуляемого перечисления с префиксом длины - PullRequest
2 голосов
/ 07 августа 2020

Этот код воспроизводит проблему:

Type Resolver(int fieldNumber)
{
    return typeof(ConsoleColor?);
}

var stream = new MemoryStream();
ConsoleColor? obj = ConsoleColor.Green;
Serializer.NonGeneric.SerializeWithLengthPrefix(stream, obj, PrefixStyle.Base128, 1);

stream.Position = 0;
Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, Resolver, out var dd);
//EXCEPTION!!!

Я просто сериализую значение перечисления, допускающее значение NULL. Но когда я пытаюсь выполнить десериализацию, я получаю следующее исключение:

ProtoBuf.ProtoException: Invalid wire-type; обычно это означает, что вы перезаписали файл без усечения или установки длины; см. https://stackoverflow.com/q/2152978/23354 '

Что я делаю не так? Есть ли способ исправить или обойти проблему? Я использую версию 2.4.6 библиотеки protobuf- net. (Невозможно перейти на 3.x, потому что я застрял на. Net Framework 4.0).

1 Ответ

3 голосов
/ 07 августа 2020

Когда вы передаете Nullable<T> в API, который принимает object, это упаковано , а правила упаковки для Nullable<T> особые: он вставляется в либо обычный null или коробку T, а не коробку T?; другими словами: object значение никогда не содержит обнуляемого типа значения. Из-за этого, с точки зрения библиотеки, вы отправили ConsoleColor, а не ConsoleColor?, поэтому:

Type Resolver(int fieldNumber)
{
    return typeof(ConsoleColor);
}

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

(Я пытаюсь понять, существует ли когда-либо a сценарий, в котором преобразователь может осмысленно вернуть typeof(Nullable<T>) для некоторого T - мы могли бы , возможно, библиотека просто развернула бы само значение, допускающее значение NULL, или создала более значимое сообщение)

...