How to create a protobuf Message instance given a MessageDescriptor (in dotnet / C#)

Viewed 1067

Context: C# / dotnet console app using Google.Protobuf 3.6.1

I want to instantiate a new protobuf message object given a MessageDescriptor only, i.e. the message types are not known at compile time.

One way is to do:

IMessage message = (IMessage)Activator.CreateInstance(messageDescriptor.ClrType);

And from here there appears to be support for runtime manipulation of message objects, e.g.

FieldDescriptor fieldDescriptor = messageDescriptor.Fields[0];
fieldDescriptor.Accessor.SetValue(message, 123)

A quick search suggests that CreateInstance(Type) is not as efficient as a compile time new Foo(), so I wondered if there was built in support that I'm missing, e.g. I was hoping for something like:

var msg = messageDescriptor.CreateMessage()

or

var msg = MessageBuilder.Create(messageDescriptor)

Activator.CreateInstance will suffice for my needs (i.e. the slower performance isn't a significant issue in my particular app/context) but I wondered if I'm missing a better/recommended approach.

1 Answers

Unfortunately not, as far as I can see at the moment.

Internally (e.g. in JsonParser) we call messageDescriptor.Parser.CreateTemplate(), but CreateTemplate() is an internal method.

I suppose you could call:

var message = messageDescriptor.Parser.ParseFrom(ByteString.Empty);

That would avoid the reflection, and I'm pretty confident it would work, but it's fairly ugly. Worth considering as an alternative...

Related