Protobuf'ta FieldDescriptor'dan mesaj alın

Oct 16 2020

Protobuf'ta (C #) farklı mesajlar ve alt mesajlar içindeki tüm alanları yazdırmak istiyorum. Nasıl mesaj türünü alıp tekrar işleve gönderebilirim (en alttaki çocuğa özyinelemeli yürüme)? Daha spesifik: Yapmam gereken, bu fieldDescriptor bir mesaj gibi mi gönderiliyor? Çözümü araştırıyorum, bu değişiklik "???".

private void PrintAllReportableFieldsinMessage(Google.Protobuf.IMessage message)
{
    foreach (var fieldDescriptor in message.Descriptor.Fields.InFieldNumberOrder())
    {
        if (fieldDescriptor.FieldType == Google.Protobuf.Reflection.FieldType.Message)
        {
            PrintAllReportableFieldsinMessage(???); // What can I send here?
        }
        else
        {
            Google.Protobuf.Reflection.FieldOptions options = fieldDescriptor.GetOptions();
            if (options != null && options.GetExtension(HelloworldExtensions.Reportable))
            {
                var fieldValue = fieldDescriptor.Accessor.GetValue(message);
                var fieldName = fieldDescriptor.Name;
                Dispatcher.Invoke(() =>
                {
                    lReadableResult.Content += fieldName + ":" + fieldValue + "|";
                });
            }
        }
    }
}

Yanıtlar

NejcGalof Oct 22 2020 at 11:40

Bir çözüm buldum. Submessage içindeki herhangi bir değer ayarlanmamışsa HasValue false döndürür. Sonra tüm varsayılan değerlere sahip yeni bir Görüntü oluşturmalıyım. O halde bu kod, tüm mesaj ve alt mesajlardaki tüm alan adlarını yazdırmak için çalışır.

private void PrintAllReportableFieldsinMessage(Google.Protobuf.IMessage message)
{
    foreach (var fieldDescriptor in message.Descriptor.Fields.InFieldNumberOrder())
    {
        if (fieldDescriptor.FieldType == Google.Protobuf.Reflection.FieldType.Message)
        {
            if (fieldDescriptor.Accessor.HasValue(message))
            {
                IMessage submessage = fieldDescriptor.Accessor.GetValue(message) as IMessage;
                PrintAllReportableFieldsinMessage(submessage);
            }
            else {
                IMessage cleanSubmessage = fieldDescriptor.MessageType.Parser.ParseFrom(ByteString.Empty);
                PrintAllReportableFieldsinMessage(cleanSubmessage);
            }
        }
        else
        {
            Google.Protobuf.Reflection.FieldOptions options = fieldDescriptor.GetOptions();
            if (options != null && options.GetExtension(HelloworldExtensions.Reportable))
            {
                var fieldValue = fieldDescriptor.Accessor.GetValue(message);
                var fieldName = fieldDescriptor.Name;
                Dispatcher.Invoke(() =>
                {
                    lReadableResult.Content += fieldName + ":" + fieldValue + "|";
                });
            }
        }
    }
}