For compatibility reasons I am writing a custom serializer for a generic 
protobuf message.

I a using Google.Protobuf 3.11.3 from NuGet and used protoc to generate my 
C# classes.

Given the proto file 

message Foo {
    optional string other = 1;
    optional Bar bar = 2;
}

message Bar {
    optional string hello = 1;
}


I have a serialize method
        public static string Serialize(IMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            
            var result = WriteFields(message, message.Descriptor.Fields, 0);
            return result.ToString();
        }

and WriteFields
        private static StringBuilder WriteFields(IMessage message, 
MessageDescriptor.FieldCollection fields, int depth)
        {
            var sb = new StringBuilder();
            foreach (var field in fields.InFieldNumberOrder())
            {
                if (field.Accessor.HasValue(message))
                {
                    if (field.FieldType == FieldType.Message)
                    {
                        sb.Append($"{field.Name} {{\n");
                        sb.Append(WriteFields(message, field.MessageType.
Fields, depth + 1));
                        sb.Append("}\n");
                    }
                    else
                    {
                        sb.Append($"{field.Name}: 
{field.Accessor.GetValue(message)}\n");
                    }
                }
            }

            return sb;
        }

The first pass of the foreach-loop runs fine. Foo.other is written as 
expected.

The second pass fails, at this point I know the field has FieldType.Message 
and I call WriteFields recursively to write the fields from Bar.

I get an InvalidCastException at field.Accessor.HasValue(message)now.  

System.InvalidCastException : Unable to cast object of type 'Test.Foo' to 
type 'Test.Bar'.
   at 
Google.Protobuf.Reflection.ReflectionUtil.ReflectionHelper`2.<>c__DisplayClass4_0.<CreateFuncIMessageBool>b__0(IMessage
 
message) in 
T:\src\github\protobuf\csharp\src\Google.Protobuf\Reflection\ReflectionUtil.cs:line
 
204
   at Test.Parser.WriteFields(IMessage message, FieldCollection fields, 
Int32 depth) in C:\src\Project\Parser.cs:line 85


I need to either
A) Convert the FieldDescriptor Bar to IMessage Bar
or
B) Find some other way to get the value than passing IMessage down the chain

I am not able to find out how to to this.



-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/protobuf/43e7707b-eaa0-472f-842f-cc69f6afa982%40googlegroups.com.

Reply via email to