当前位置: 首页 > news >正文

C#核心学习(十六)面向对象--关联知识点(2)string和Stringbuilder

引言

        在C#开发中,字符串处理是日常编码的基础需求。然而stringStringBuilder的选择常常引发困惑——何时该用不可变的string?什么场景下必须选择可变的StringBuilder?本文将深入剖析两者的核心差异,并通过完整API对比给出实用建议。


一、String类的特性与应用

1.1 不可变性的本质

string s = "Hello";
s += ", World!"; // 实际创建了新对象
Console.WriteLine(s); // 输出"Hello, World!"

每次修改都会生成新实例,原内存无法回收(需依赖GC) 

1.2 核心API方法

string 类 API 汇总

方法/属性描述示例
静态方法
Concat(params string[])连接多个字符串string.Concat("A", "B", "C"); // "ABC"
Format(string, params object[])格式化字符串string.Format("Name: {0}", "Alice"); // "Name: Alice"
Join(string, string[])用分隔符连接字符串数组string.Join(",", new[]{"A", "B"}); // "A,B"
IsNullOrEmpty(string)检查字符串是否为空或 nullstring.IsNullOrEmpty(""); // true
IsNullOrWhiteSpace(string)检查是否为空、null 或仅包含空白字符string.IsNullOrWhiteSpace(" "); // true
实例方法
Length (属性)获取字符串长度int len = "Hello".Length; // 5
Substring(int start, int length)提取子字符串"Hello".Substring(1, 3); // "ell"
Split(params char[])按分隔符分割字符串"A,B,C".Split(','); // ["A", "B", "C"]
Replace(string old, string new)替换子字符串"abc".Replace("a", "X"); // "Xbc"
Contains(string)判断是否包含子字符串"Hello".Contains("ell"); // true
StartsWith(string) / EndsWith(string)检查开头或结尾"Hello".StartsWith("He"); // true
ToUpper() / ToLower()转换为全大写或全小写"Abc".ToUpper(); // "ABC"
Trim()移除前后空白字符" text ".Trim(); // "text"
IndexOf(char/string)查找字符或子字符串的位置"Hello".IndexOf('e'); // 1

这里查找字符的位置还有一个后向查找的LastIndexOf和这里用法一样 

注意这里的替换,是指将所有相同的内容全部替换。 

二、StringBuilder的进阶用法

2.1 可变性的性能优势

StringBuilder sb = new StringBuilder(100); // 预分配容量
for(int i=0;i<1000;i++){
    sb.Append($"Item {i}");
}
// 最终一次内存分配
string result = sb.ToString();

2.2 关键API详解

StringBuilder 类 API 汇总

方法/属性描述示例
构造方法
StringBuilder()创建空 StringBuildervar sb = new StringBuilder();
StringBuilder(string)用初始字符串创建var sb = new StringBuilder("Hello");
核心方法
Append(string)追加内容到末尾sb.Append(" World");
AppendLine(string)追加内容并换行sb.AppendLine("Next Line");
Insert(int index, string)在指定位置插入内容sb.Insert(0, "Start: ");
Remove(int start, int len)移除指定范围的字符sb.Remove(0, 5);
Replace(string, string)替换所有匹配的子字符串sb.Replace("old", "new");
Clear()清空内容sb.Clear();
ToString()转换为 stringstring result = sb.ToString();
属性
Length (属性)当前内容的长度int len = sb.Length;
Capacity (属性)动态分配的容量(可设置)sb.Capacity = 1024;

三、什么时候用什么

        前面我们说了,string,每次拼接一个字符串,其实是会产生一个新的字符串,在多次的【拼接下,会十分的消耗性能,浪费内存,所以我们必须区分什么时候使用string,什么时候使用stringbulider优化,每一种设计出来的对象类型都会有它的作用的!

优先使用String的场景
场景特征推荐方案典型案例
单次赋值string硬编码常量
const string AppName = "MyApp"
少量拼接stringvar msg = baseMsg + DateTime.Now.ToString()
LINQ查询stringWhere(x => x.Name.Contains("admin"))
多线程共享string跨线程传递只读数据
使用StringBuilder的场景
场景特征推荐方案性能对比数据
循环内拼接StringBuilder1000次循环:string耗时1200ms vs sb8ms
不确定长度StringBuilder动态增长比反复分配节省70%内存
复杂格式化StringBuilder支持AppendFormat等高级操作
大文本处理StringBuilder10万字符操作性能提升20倍

关键点总结

  • string:不可变类型,每次修改都会创建新对象,适合少量修改或固定文本操作。

  • StringBuilder:可变类型,直接在内存中修改内容,适合高频字符串拼接或大规模修改(如循环中操作)。

根据需求选择:需要性能时用 StringBuilder,简单场景用 string

相关文章:

  • 案例驱动的 IT 团队管理:创新与突破之路: 第四章 危机应对:从风险预见到创新破局-4.1.3重构过程中的团队士气管理
  • 202524 | 分布式事务
  • 《基于 RNN 的股票预测模型代码优化:从重塑到直接可视化》
  • 设计模式——抽象工厂模式总结
  • AcWing 6093. 不互质子序列
  • ubuntu 安装samba
  • 奇葩问题:PGPOOL自动容灾切换,主备不生效原因
  • 部署YUM仓库
  • 卡码网55:右旋字符串
  • 【android bluetooth 框架分析 02】【Module详解 3】【HciHal 模块介绍】
  • 【tRPC-go】message、context相关源码设计思路
  • vue 入门:生命周期
  • 【第16届蓝桥杯C++C组】--- 数位倍数
  • Leetcode:二叉树
  • 简述一下Unity的UnityWebRequest
  • 第二届电气技术与自动化工程国际学术会议 (ETAE 2025)
  • STM32 低功耗模式下 RTC唤醒 和 PA0唤醒 的配合使用
  • HTML — 定位
  • leetcode精选合集(更新中)
  • Istio常用命令
  • 深交所修订创业板指数编制方案,引入ESG负面剔除机制
  • 国家网信办举办在欧中资企业座谈会,就数据跨境流动等进行交流
  • 上海国际咖啡文化节开幕,北外滩集结了超350个展位
  • 广东省副省长刘红兵跨省任湖南省委常委、宣传部部长
  • 普京与卢卡申科举行会晤,将扩大在飞机制造等领域合作
  • 东风着陆场近日气象条件满足神舟十九号安全返回要求