C# Google.ProtocolBuffers Метод десериализации (proto3)

Я недавно обновил свою кодовую базу (Java, C++ и C#) для использования proto3. В случае с C# это повлекло за собой более 2000 изменений в коде. Это в основном семантическое и все хорошее, но есть одна проблема, которую я не могу понять; сериализации / десериализации. У меня есть следующий исправленный метод для десериализации моего IMessage типы (код для этого в proto2 прокомментирован), этот код показан в примерах в репозитории GitHub...

public static T ToObject<T>(this byte[] buf) where T : IMessage 
{
    if (buf == null)
        return default(T);

    using (MemoryStream ms = new MemoryStream())
    {
        ms.Write(buf, 0, buf.Length);
        ms.Seek(0, SeekOrigin.Begin);

        MessageParser parser = new MessageParser();
        return (T)parser.ParseFrom(ms);
            //ProtoBuf.Serializer.Deserialize<T>(ms);
    }
}

но линия MessageParser parser = new MessageParser(); дает мне ошибку дизайна / компиляции

MessageParser не содержит конструктор, который содержит 0 аргументов

Что ж, это любопытно, поскольку я знаю о документах proto3, которые говорят мне об обратном.

Все, что я хочу знать, с помощью proto3, как я могу выполнить свою десериализацию?

Спасибо за ваше время.


Обратите внимание, мой код сериализации

public static byte[] ToByteArray<T>(this T o) where T : IMessage 
{
    if (o == null)
        return null;

    using (MemoryStream ms = new MemoryStream())
    {
        o.WriteTo(ms);
        return ms.ToArray();
    }
}

Это компилируется, но так ли это?

1 ответ

Решение

В случае ошибки при компиляции десериализации в документации сказано, что вы должны передать Func<T> как фабрика функций для создания экземпляров T конструктору MessageParser<T>,

Возможно () => new T() или более сложная функция в зависимости от того, что нужно для создания ваших сообщений.

Полный код:

public static T ToObject<T>(this byte[] buf) where T : IMessage<T>, new()
{
    if (buf == null)
        return default(T);

    using (MemoryStream ms = new MemoryStream())
    {
        ms.Write(buf, 0, buf.Length);
        ms.Seek(0, SeekOrigin.Begin);

        MessageParser<T> parser = new MessageParser<T>(() => new T());
        return parser.ParseFrom(ms);
    }
}

Как сказано в документации, сериализация должна быть в порядке.

Другие вопросы по тегам