C# 字符串拼接的 7 种方式及性能对比

简介

C# 提供多种字符串拼接方式,每种方式在性能和可读性上都有其特点。

方法

使用 + 号直接拼接

最简单直观的方式,用于拼接少量字符。

csharp 复制代码
string str1 = "Hello";
string str2 = "World";
string result = str1 + " " + str2;
  • 优点:代码简单直观
  • 缺点:拼接大量字符串时效率较低,生成大量临时对象。

使用 + 号拼接字符串会生成大量临时对象的原因在于字符串在 .NET 中是 不可变的。每次进行字符串拼接时,都会创建一个新的字符串对象,而不是对原字符串进行修改。对于较少次数的拼接,这种性能影响较小;但如果拼接操作多次循环执行,内存分配和垃圾回收的开销会显著增加。

使用 .NET Profiler 工具如 dotMemory[Visual Studio Diagnostic Tools] 可以直观地观测到内存分配的情况

使用 string.Concat 方法

专门用于字符串拼接。

csharp 复制代码
string result = string.Concat("Hello", " ", "World");
  • 优点:适合多个字符串的直接拼接。
  • 缺点:无格式化功能。
使用 string.Format 方法

支持格式化的拼接方式。

csharp 复制代码
string name = "John";
string result = string.Format("Hello, {0}!", name);
  • 优点:可以灵活地插入变量,适合格式化字符串。
  • 缺点:相较于 $ 字符串插值略显冗长。
使用 $ 字符串插值法

C# 6.0 开始支持,是一种更加现代的格式化拼接方式。

csharp 复制代码
string name = "John";
string result = $"Hello, {name}!";
  • 优点:简洁直观,可读性强。
  • 缺点:内部与 string.Format 类似,性能差异不大。
使用 StringBuilder

适合大量字符串的动态拼接。

csharp 复制代码
var builder = new StringBuilder();
builder.Append("Hello");
builder.Append(" ");
builder.Append("World");
string result = builder.ToString();
  • 优点:性能优越,特别是在循环中拼接大量字符串时。
  • 缺点:需要更多代码,略微增加复杂性。

StringBuilder 的底层实现:

  • 内部使用一个动态扩展的字符数组来存储数据。
  • 默认初始容量为 16 个字符(可以通过构造函数自定义)。
  • 当字符数组容量不足时,会按一定比例自动扩展(通常是原容量的 2 倍)。

这种机制避免了频繁分配内存的开销:拼接小量数据时,内存使用非常高效;即使需要扩展缓冲区,扩展次数也远少于每次创建新字符串的情况。

使用 string.Join

用于连接数组或集合中的字符串。

csharp 复制代码
string[] words = { "Hello", "World" };
string result = string.Join(" ", words);
  • 优点:简洁方便,适合处理数组或集合。
  • 缺点:需要传入分隔符,不适合普通字符串拼接。
使用 string interpolation

适用于多行或复杂格式的字符串拼接。

csharp 复制代码
string name = "John";
string result = $"""
Hello,
{name}!
Welcome to C# 10.0
""";
  • 优点:支持多行字符串拼接和插值,代码更简洁。
  • 缺点:需要使用 C# 10.0 或更高版本。

性能对比

  1. 对于少量字符串拼接,+$(字符串插值)是最简单的选择。
  2. 对于大量字符串拼接,StringBuilder 更加高效。
  3. 对于集合或数组拼接,string.Join 是最佳选择。

推荐使用

  • 小规模拼接:+ 或 `$ 字符串插值。
  • 大规模拼接:StringBuilder
  • 集合拼接:string.Join
相关推荐
冰茶_1 小时前
C#中常见的设计模式
java·开发语言·microsoft·设计模式·微软·c#·命令模式
chegan3 小时前
用c#从头写一个AI agent,实现企业内部自然语言数据统计分析(二)-数据结构和代码分析方法
ai·c#·agent
煤烦恼3 小时前
Kafka 命令行操作与 Spark-Streaming 核心编程总结
c#·linq
Zhen (Evan) Wang5 小时前
.NET 6 + Dapper + User-Defined Table Type
sqlserver·c#·.net·wpf
FAREWELL000756 小时前
C#进阶学习(十四)反射的概念以及关键类Type
开发语言·学习·c#·反射·type
FAREWELL000756 小时前
C#进阶学习(十三)C#中的预处理器指令
开发语言·学习·c#·预处理指令
qq_297908016 小时前
c#简易超市充值卡程序充值消费查余额
经验分享·sqlserver·开源·c#·.net·开源软件
浅陌sss7 小时前
C#中的弱引用使用
c#
云上空8 小时前
C#初级知识总结
开发语言·c#
钢铁男儿8 小时前
C# 深入理解类:面向对象编程的核心数据结构
开发语言·数据结构·c#