问题
In protobuf (C#) I want to print all fields inside different messages and submessages. How can I get message type and send to function again (recursive walking to lowest child)? More specific: What I must do, that fieldDescriptor is send like a message? I search solution, which is change "???".
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 + "|";
});
}
}
}
}
回答1:
I found a solition. HasValue return false, if any values inside submessage are not set. Then I must create a new Imessage which have all default values. So then this code works for printing all field names in all messages and submessages.
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 + "|";
});
}
}
}
}
来源:https://stackoverflow.com/questions/64391067/get-message-from-fielddescriptor-in-protobuf