2013-03-11 3 views
1

Значения по умолчанию для классов, сгенерированных с помощью протогена, по-видимому, не сериализованы, когда UseImplicitZeroDefaults = false.UseImplicitZeroDefaults для сгенерированных классов protobuf

У меня есть небольшой .proto файл:

package protobuf; 

option java_package = "com.company.protobuf"; 
option java_outer_classname = "Test"; 

message TestMessage{   
    optional string Message = 1; 
    optional bool ABool = 2; 
    optional int32 AnInt = 3;   
} 

Использования protogen.exe, я генерируюсь TestMessage класса, который я пытаюсь отправить туда и обратно через провод к приложению Java. Я не могу заставить protobuf-net сериализовать значение нуля для AnInt или false для ABool, включая настройку UseImplicitZeroDefaults=false. Однако использование аннотированных классов для сериализации с этим параметром работает. Вот эквивалентный класс, который я генерируемой:

[ProtoContract] 
class Test2 
{ 
    [ProtoMember(1)] 
    public string Message { get; set; } 
    [ProtoMember(2)] 
    public bool ABool { get; set; } 
    [ProtoMember(3)] 
    public int AnInt { get; set; } 
} 

Инициализация два класса с теми же данными и сериализация byte[] показывает, что четыре дополнительных байт поступает из аннотированного класса.

... 
private static readonly RuntimeTypeModel serializer; 
static Program() 
{ 
    serializer = TypeModel.Create(); 
    serializer.UseImplicitZeroDefaults = false; 
    Console.WriteLine(serializer.UseImplicitZeroDefaults); //prints false 
} 

static void SendMessages(ITopic topic, ISession session) 
{ 
    Console.WriteLine(serializer.UseImplicitZeroDefaults); 

    TestMessage t = new TestMessage(); 
    t.ABool = false; 
    t.AnInt = 0; 
    t.Message = "Test Message"; 

    using (var o = new MemoryStream()) 
    { 
     serializer.Serialize(o, t); 
     Console.WriteLine(string.Format("Tx: Message={0} ABool={1} AnInt={2}", t.Message, t.ABool, t.AnInt)); 
     Console.WriteLine(o.ToArray().Length); 
    } 

    Test2 t2 = new Test2(); 
    t2.ABool = false; 
    t2.AnInt = 0; 
    t2.Message = "Test Message"; 
    using (var o = new MemoryStream()) 
    { 
     serializer.Serialize(o, t2); 
     Console.WriteLine(string.Format("Tx: Message={0} ABool={1} AnInt={2}", t.Message, t.ABool, t.AnInt)); 
     Console.WriteLine(o.ToArray().Length); 
    } 
} 

Выход:

False 
Tx: Message=Test Message ABool=False AnInt=0 
14 
Tx: Message=Test Message ABool=False AnInt=0 
18 

Есть ли настройки я пропавшими без вести? Или классы, созданные из .proto-файлов, используют другой механизм для сериализации? В идеальном мире я бы ожидал, что настройка UseImplicitZeroDefaults будет воспринята как аннотированными, так и сгенерированными классами на пути через сериализатор.

ответ

1

Если вы добавите -p:detectMissing на ваш звонок до protogen, он должен испускать код, следуя другому шаблону, который позволяет лучше отслеживать их. В принципе, он должен делать то, что вам нужно.

+0

Это работает. И я узнал о типах с нулевым значением. Благодарю. – dmcauslan

Смежные вопросы