protobuf- net преобразует список <T>в класс List_T при использовании .ToProto () - PullRequest
1 голос
/ 14 февраля 2020

У меня есть требование взять библиотеку C# классов, которые реализуют protobuf-net, и преобразовать их в файлы .proto, которые необходимо преобразовать с помощью protoc в файлы .py. Я понимаю, что функция .ToProto() прекрасно справляется с этой задачей, но я столкнулся с проблемой, связанной с коллекциями и обобщениями при преобразовании файлов .proto в .py. При попытке сериализации списка DateTimes, например, я получаю следующую ошибку X.proto:64:13. "List_TimeSpan" is not defined. Поскольку это не вызвало проблемы при сериализации в файл protobuf, я не знал об этой ситуации в то время.

В настоящее время я использую proto-buf.net 2.3.2 для этого проекта; это версия, с которой была проделана моя другая работа, и я знаю, что это можно решить только с помощью обновления версии. Я просто не уверен, что это ответ с копанием, которое я сделал до сих пор. Если я что-то упустил, я был бы очень признателен за любую помощь, которая может быть оказана мне.

1 Ответ

2 голосов
/ 14 февраля 2020

Если мы рассмотрим:

[ProtoContract]
public class Foo {
    [ProtoMember(12)]
    public List<DateTime> Times { get; } = new List<DateTime>();
}

, то GetProto<T>() в v2.3.2 (версия, упомянутая в вопросе) и v2.4.4 (текущая версия по умолчанию) сгенерирует:

syntax = "proto2";
import "protobuf-net/bcl.proto"; // schema for protobuf-net's handling of core .NET types

message Foo {
   repeated .bcl.DateTime Times = 12;
}

Итак, на поверхности , это уже должно быть просто отлично. Если вы делаете что-то более экзотическое c (возможно, пользуетесь списком в значении словаря?), Я был бы рад помочь, но мне понадобится больше информации о том, что вы делаете. Публикация некоторого C#, который показывает, что вы видите, будет отличным началом.


Обратите внимание, что когда впервые появился protobuf- net, не было согласованного формата передачи для даты. / значения, подобные времени, поэтому protobuf- net что-то придумал, но получается, что , а не будет удобной для кроссплатформенной работы; следующее - серьезное изменение (оно не совместимо с данными), но, если возможно, я настоятельно рекомендую известный формат, добавленный Google позже:

[ProtoContract]
public class Foo {
    [ProtoMember(12, DataFormat = DataFormat.WellKnown)]
    public List<DateTime> Times { get; } = new List<DateTime>();
}

, который генерирует :

syntax = "proto2";
import "google/protobuf/timestamp.proto";

message Foo {
   repeated .google.protobuf.Timestamp Times = 12;
}
...