C#字符串拼接优先用$插值字符串,简单场景用string.Concat(),高频循环必须用StringBuilder;避免无脑+连接,尤其循环中。
直接说结论:C# 拼接字符串优先用插值字符串,简单场景用,高频循环拼接必须用;别再无脑用连接多个变量,尤其在循环里。
什么时候该用
插值而不是
?
插值不是语法糖的“炫技”,它在编译期就被优化成
或更优的内联处理,可读性和性能都更好。而
在涉及多个非字面量时会隐式调用多次
,生成临时字符串对象。
推荐:
—— 清晰、类型安全、支持格式化
不推荐:
—— 多次装箱、易错、难维护
注意:
后不能跟换行(除非用逐字字符串
),且大括号内不能直接写未声明变量,比如
合法,
可能抛
和
的分工边界
是纯拼接,不做分隔;
是带分隔符的聚合,底层都避免了中间字符串分配,比
更可控。
拼数组/集合无分隔:用
,比
快且内存友好
需要逗号分隔:用
,它内部做了长度预估,不会反复扩容
错误用法:
会抛
;要容错得先过滤或用
为什么循环中拼字符串必须用
?
假设循环 1000 次,每次拼一个短字符串:
会产生约 O(n²) 次内存拷贝(因为字符串不可变),而
默认容量 16,自动倍增扩容,最终只分配几次大块内存。
C知道
CSDN推出的一款AI技术问答工具
下载
初始化建议:
—— 如果能预估总长,直接设容量,避免多次
追加内容用
或
,别混用
常见坑:
中如果
或
是
,
不会崩,但语义可能不对;更稳妥是
和
能替代拼接吗?
它们不用于“拼接”,而是用于零分配的字符串切片和写入——适合高性能日志、协议解析等场景,但要求目标缓冲区已存在且大小可控。
典型用途:
不能直接拼:
本身不增长,也不管理内存生命周期;想“拼”就得自己算偏移、检查长度,出错就是
适用前提:你知道所有片段长度之和 ≤ 缓冲区大小,且不需要返回
(否则还得调
触发一次分配)
真正难的不是选哪个 API,而是判断「这个拼接是否在热路径里」以及「结果会不会被长期持有」。很多性能问题不是拼法错了,是根本没必要拼——比如日志模板可以预编译,SQL 拼接应该交给参数化查询。
$"string.Concat()StringBuilder+$"+string.Format()+string.Concat()$"用户 {name} 登录时间 {DateTime.Now:HH:mm}""用户 " + name + " 登录时间 " + DateTime.Now.ToString("HH:mm")$@$"${x?.Length ?? 0}${x.Length}NullReferenceExceptionstring.Concat()string.Join()Concat()Join()+string.Concat(strArray)strArray.Aggregate((a,b) => a+b)string.Join(", ", list)string.Join("", new[] { "a", null, "c" })ArgumentNullException?.ToString() ?? ""StringBuilder+StringBuildernew StringBuilder(2048)Array.Copy.Append().AppendLine().ToString() + "xxx"sb.Append(x.ToString()).Append(y.ToString())xynullToString()sb.Append(x?.ToString() ?? "")SpanMemoryvar buffer = stackalloc char[512]; var span = buffer.AsSpan(); span[..4].CopyTo(destination);spanIndexOutOfRangeExceptionstringToString()