Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize Google Protobuf RepeatedField collections

When you try to initialize a repeated field member (property) of already generated Google Protobuf message type, you can't use a setter since they are read-only.

How to initialize google Protobuf message's RepeatedField collections?

like image 478
sbp Avatar asked Dec 12 '19 06:12

sbp


2 Answers

Although it's a bit weird syntax, you can actually use a collection inside a collection initializer on a RepeatedField like this:

var promotions = new List<Promotion>(); 
// code to populate promotions 
var price = new Price() { Promotions = { promotions } };

This works because RepeatedField defines a custom collection initializer (overload for Add that takes IEnumerable<T>).

I guess this was a workaround so these fields could be declared readonly within messages, but still work with collection initializers.

like image 106
Peter Wishart Avatar answered Sep 17 '22 15:09

Peter Wishart


The collection property/member generated from repeated on .proto files are read-only. They get initialized as soon as you new up an instance of your generated protobuf type. Since it is a read-only collection, you can't set it to another instance but you could add elements to already created instance.

You need to use Google Protobuf .net library's extension methods (for me which was not intuitive since at the time of writing this article I wasn't getting IntelliSense support in VS 2019) for doing so.

For example, if your protobuf generated type is Price which happens to have a repeated field/collection Promotion like repeated Promotion promotions = <some int> then you'd do

var price = new Price(); //just placeholder for already generated message
//other code
var promotions = new List<Promotion>(); //List is just an example
//code to populate promotions 
price.Promotions.Add(promotions);

Official reference link

like image 28
sbp Avatar answered Sep 18 '22 15:09

sbp