跳转到主内容
极星编程网:以代码为星,赴技术山海!

c#如何拼接字符串_c#拼接字符串完整指南一文搞懂

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

相关文章