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

C# 字符串与集合核心知识梳理

一、思维导图

以下是本文内容的整体知识脉络,使用 XMind 绘制:

思维导图详解

1. string 类基础(sealed / char[] / 不可变 / .Length)

`string` 是 C# 中最常用的类型之一,但它有几个关键特性:**sealed 修饰意味着不能被继承**,保证了字符串行为的统一性;**底层是一个 `char[]` 字符数组**,通过 `.Length` 获取字符个数。最重要的一点——**字符串不可变**:任何对字符串的"修改"操作(如替换、拼接)实际上都会创建一个全新的字符串对象,原字符串保持不变。这带来了线程安全和字符串驻留的优势,但也意味着频繁拼接会有性能开销。

2. 查找(IndexOf / LastIndexOf,-1)

`IndexOf` 查找子串或字符**首次出现的位置**,`LastIndexOf` 查找**最后一次出现的位置**,两者都**区分大小写**。如果未找到目标内容,统一返回 **-1**,这是判断是否包含指定内容的标准方式。

3. 截取判断(Substring / StartsWith / EndsWith / IsNullOrEmpty)

`Substring` 用于截取子字符串,指定起始索引和长度。`StartsWith` / `EndsWith` 分别判断字符串是否以指定内容**开头**或**结尾**,返回 `bool`,常用于文件扩展名校验、URL 前缀判断等场景。`IsNullOrEmpty` 是静态方法,用于同时判断字符串是否为 `null` 或空字符串 `""`,是防御性编程的常用手段。

4. 大小写转换(ToUpper / ToLower → 验证码)

`ToUpper` 转大写、`ToLower` 转小写。一个经典应用场景是**验证码校验**:将用户输入和正确答案统一转为大写(或小写)后再比较,实现忽略大小写的匹配。

5. 其他操作(Split / Replace / Trim / ToCharArray)

- **Split**:按指定分隔符将字符串拆分为 `string[]`,常用于解析 CSV、日志行等格式化文本。

- **Replace**:替换指定内容,返回新字符串,**原字符串不变**(不可变性的体现)。

- **Trim**:去除首尾空白字符(空格、制表符、换行等),常用于清洗用户输入。

- **ToCharArray**:将字符串转换为 `char[]`,便于逐字符处理。

6. StringBuilder(Append / Insert / Remove)

当需要频繁拼接字符串时,直接用 `+` 会不断创建新对象,性能极差。`StringBuilder` 内部维护一个**可变的字符缓冲区**:

- **Append**:在末尾追加内容。

- **Insert**:在指定位置插入内容。

- **Remove**:删除指定范围的字符。

最终通过 `ToString()` 一次性生成字符串,大幅减少内存分配。

7. LINQ & 枚举(GetEnumerator → foreach)

LINQ(Language Integrated Query)提供了一套针对集合和序列的**声明式查询语法**,如 `Where`、`Select`、`OrderBy` 等,让数据筛选和转换变得简洁优雅。`GetEnumerator` 返回枚举器,是实现 `foreach` 遍历的底层机制——任何实现了 `IEnumerable` 的类型都可以用 `foreach` 直接遍历。

8. 异常处理(try-catch / throw)

`try-catch` 用于**捕获并处理异常**,防止程序崩溃。`throw` 用于**主动抛出异常**,向调用方传递错误信息。两者配合构成 C# 的异常处理体系,是编写健壮程序的基础。

9. 集合类型(数组 / LinkedList / Hashtable)

- **数组**:定长、连续内存分配,索引访问速度最快 O(1)。

- **链表 LinkedList**:节点通过指针连接,增删操作 O(1) 无需移动元素,适合频繁插入删除的场景。

- **哈希表 Hashtable**:基于哈希算法实现键值对存储,查找、插入、删除均为近似 O(1)。

10. HashSet & Dictionary(不重复 / 键值对)

- **HashSet**:无序集合,**元素不可重复**,常用于去重和集合运算(交集、并集、差集)。

- **Dictionary**:无序的键值对集合,**Key 不允许重复,Value 允许重复**。通过 Key 查找 Value 为 O(1),是替代多重 `if-else` 或 `switch` 的优雅方案。

11. 委托(方法作类型 / 匿名 → Lambda)

**委托**是将方法当作数据类型来传递的机制,本质上是一个指向方法的类型安全的指针。从具名方法 → 匿名方法 → Lambda 表达式,语法逐步精简:

// 具名方法

Func<int, int, int> add = Add;

// 匿名方法

Func<int, int, int> add = delegate(int a, int b) { return a + b; };

// Lambda

Func<int, int, int> add = (a, b) => a + b;

委托是事件驱动、回调函数、LINQ 表达式的基石。

12. DateTime(DateTime.Now)

`DateTime.Now` 获取当前系统时间对象,包含年、月、日、时、分、秒等属性。常用于日志记录、计时、定时任务等场景。

二、最近遇到的问题与解题思路

问题:大批量字符串拼接导致内存暴涨

在做一个日志分析工具时,需要对几十万行文本进行拼接输出,最初代码直接使用 `+` 拼接:

string result = "";

foreach (var line in lines)

{

result += line + "\n"; // 每次循环生成新字符串对象

}

结果程序运行非常慢,内存持续飙升。排查后发现:**string 是不可变的,每次 `+=` 都会在堆上分配一个新字符串对象**,几十万次循环就产生了海量垃圾对象,GC 频繁触发,CPU 和内存双双吃紧。

解题思路

1. **找准根因**:string 的不可变性是设计使然(线程安全、字符串驻留池等优势),但在频繁拼接场景下恰恰是性能杀手。

2. 选择合适工具——`StringBuilder`:

StringBuilder sb = new StringBuilder();

foreach (var line in lines)

{

sb.Append(line).Append("\n");

}

string result = sb.ToString();

`StringBuilder` 内部维护一个可变的 `char[]` 缓冲区,`Append` 直接在缓冲区末尾写入,无需每次分配新对象,性能提升数十倍。

3. 延伸思考:

- 少量固定拼接(<5 次)用 `+` 即可,编译器会优化为 `string.Concat`

- 循环拼接、条件拼接 → 必须用 `StringBuilder`

- 分隔符拼接直接用 `string.Join` 更简洁,底层同样是高效实现

> 一句话总结:理解 string 底层是 `char[]` 且不可变,才能在合适的场景选用 `StringBuilder`、`string.Join` 等正确的工具,避免"字符串拼接"成为性能瓶颈。

http://www.jsqmd.com/news/1091912/

相关文章:

  • 告别time.sleep:用Playwright网络控制实现精准页面加载
  • Fillinger智能填充脚本:自动化设计元素分布的革命性解决方案
  • 为什么你的ChatGPT API调用延迟飙升300ms?揭秘OpenAI边缘节点路由策略、retry机制失效根源及自研重试框架代码(附GitHub可运行Demo)
  • 码哥用扣子搭了一套自动跟进工作流,每天省2小时这不是夸张
  • 149、 PCIE Linux设备驱动编写入门:从一次诡异的设备失联说起
  • NucleusCoop分屏游戏终极指南:单机变多人,轻松享受本地联机乐趣
  • CVE-2024-38816 SSRF漏洞实战:从原理剖析到多层防御体系构建
  • Java计算机毕设之基于 JavaWeb 的油田物料申领审批管理系统 油田物资入库出库盘点一体化管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 工业 DC-DC 非隔离模块电源硬件选型参数技术解析|K7812M-1000R3 和钡特电源 N7812-1000 优质稳定供应丨国产丨参数规格
  • 从满额到冻结:ChatGPT Plus额度耗尽后的72小时连锁反应(含API错误码对照表+应急回滚方案)
  • 银河麒麟服务器操作系统实战:基于nmcli的Bond与VLAN-Bond高级网络配置详解
  • 完全免费的跨平台开源音乐播放器:LX Music桌面版终极使用指南
  • 微信读书出官方 Skill 了,但我用了一天发现它还差关键一步
  • Stateflow状态机建模:嵌套状态
  • 当AI智能体遇上高并发:我是怎么用Redis+负载均衡干掉推理超时的
  • Node Exporter 核心指标监控实战:从数据采集到告警配置
  • OpenAI重磅发布GPT-5.6:三款AI模型强势登场,性能远超谷歌Anthropic,但普通人无缘使用!
  • 时间复杂度与空间复杂度在实际工程中如何权衡取舍?
  • TI评估模块安全合规指南:从硬件开发到全球市场准入
  • IM系统端到端加密实战:从Signal协议到密钥管理全解析
  • OpenEuler24.03 LTS sp2 换软件源
  • Claude API 鉴权失败:Key、权限和配置怎么查
  • 零壹教育:列表推导式到底好在哪?从新手循环到Pythonic的必经之路
  • 铰链滑轨如何分辨好坏,国内家具五金品牌对比参考
  • 人造太阳(托卡马克聚变堆)
  • MOSFET 场效应管笔记总结
  • 中继镜实战:从参数解析到图卡选型的完整测试指南
  • 夸克网盘自动化神器:三分钟搞定追剧转存,彻底告别手动操作
  • 你是不是也受够了配置丢失的苦?
  • 存储器映射