1

I'm using protocol buffers in .net, and generating C# classes using protoc. For example, lets take this proto3 file from https://developers.google.com/protocol-buffers/docs/proto3:

message SearchResponse {
  repeated Result results = 1;
}

message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

And lets try to initialize the generated C# classes.

They look something like this

public class SearchResponse
{
    public RepeatedField<Result> Results { get; } = new RepeatedField<Result>();
}

public class Result
{
    public string Url { get; set; }
    public string Title { get; set; }
    public RepeatedField<string> Snippets { get; } = new RepeatedField<string>();
}

Now lets try to initialise this. Ideally I would want to be able to do something like this:

SearchResponse GetSearchResponse => new SearchResponse
{
    Results = new RepeatedField<SearchResponse>
    {
        new Result
        {
            Url = "..."
            Title = "..."
            Snippets = new RepeatedField<string> {"a", "b", "c"}
        }
    }
};

However since the collections don't have setters, instead I must initialize this across multiple expressions:

SearchResponse GetSearchResponse
{
    get
    {
        var response = new SearchResponse();
        var result = new Result
        {
            Url = "..."
            Title = "..."
        }
        result.Snippets.AddRange(new[]{"a", "b", "c"});
        response.Results.Add(result);
        return response;
    }
}

And what would ideally take one expression is spread acrossa mixture of 5 expressions and statements.

Is there any neater way of initializing these structures I'm missing?

Yair Halberstadt
  • 5,733
  • 28
  • 60

1 Answers1

2

RepeatedField<T> implements the list APIs, so you should be able to just use a collection initializer without setting a new value:

new SearchResponse {
    Results = {
        new Result {
            Url = "...",
            Title = "...",
            Snippets = { "a", "b", "c" }
        }
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • You know, I contribute to both Roslyn, and the C# language design discussion, and I never knew you could do that without initialising the collection first! You learn something new every day! Thanks – Yair Halberstadt Jan 31 '19 at 06:53