You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET中用单表达式初始化Protocol Buffers生成的C#类?

简洁初始化Protobuf生成的带只读RepeatedField的C#类

这个问题我太有共鸣了——protobuf生成的C#类里那些只读的RepeatedField确实会打断我们想用对象初始化器写单表达式的流畅感!不过其实有几个巧妙的办法能让你回到简洁的单表达式初始化,不用拆分成多步。

最推荐:利用C#集合初始化器语法糖

你可能不知道,C#的集合初始化器不仅可以用来创建新集合,还能对已存在的集合调用Add方法——而RepeatedField刚好实现了支持这个语法的接口(它有Add方法,并且实现了IEnumerable)。所以你完全可以这样写:

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

这里的Results = { ... }和Snippets = { ... }并不是给属性赋值(毕竟没有setter),而是C#帮你自动调用了Results.Add(...)和Snippets.Add(...),完美实现单表达式初始化,和你最开始的理想写法几乎一样!

进阶:用扩展方法实现链式初始化

如果你的初始化逻辑更复杂,或者想让代码可读性更强,可以写个简单的扩展方法来封装AddRange之类的操作:

public static class ProtobufExtensions
{
    public static Result WithSnippets(this Result result, params string[] snippets)
    {
        result.Snippets.AddRange(snippets);
        return result;
    }
}

然后就能用链式调用的方式初始化:

SearchResponse GetSearchResponse => new SearchResponse
{
    Results =
    {
        new Result { Url = "...", Title = "..." }.WithSnippets("a", "b", "c")
    }
};

这种方式特别适合需要给集合批量添加元素,或者想把初始化逻辑复用的场景。

批量初始化多个元素的场景

如果要一次性添加多个Result,同样可以用集合初始化器直接搞定:

SearchResponse GetSearchResponse => new SearchResponse
{
    Results =
    {
        new Result { Url = "url1", Title = "title1", Snippets = { "s1", "s2" } },
        new Result { Url = "url2", Title = "title2", Snippets = { "s3" } }
    }
};

本质还是C#帮你逐个调用Results.Add(),完全不需要手动创建中间集合再AddRange。


内容的提问来源于stack exchange,提问作者Yair Halberstadt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:07:28