4、C#语言基础(中):字符串操作、数组、集合、控制流语句
好,咱们接着聊。上一章我们把C#的变量、类型和运算符过了一遍,算是打了个地基。这一章,咱们要开始搭框架了——字符串、数组、集合,还有控制流。这些东西,说白了就是你每天写代码都要碰的。我做了十几年Windows桌面开发,可以负责任地告诉你:这部分学扎实了,后面写WPF、WinForms会顺手很多。
4.1 字符串操作:不只是拼接
字符串在C#里是个引用类型,但用起来像值类型。嗯,这里要注意:字符串是不可变的。你每次修改字符串,其实都是创建了一个新对象。我在项目中遇到过有人在一个循环里疯狂拼接字符串,结果界面卡死——后来换成StringBuilder,问题秒解。
4.1.1 常用方法
- Length:获取字符串长度。比如
"你好".Length返回2。 - IndexOf / LastIndexOf:查找某个字符或子串的位置。找不到返回-1。
- Substring:截取子串。记得参数是起始索引和长度。
- Replace:替换。我经常用它来清理用户输入里的特殊字符。
- Split:按分隔符拆分成数组。解析CSV文件时必备。
- Trim / TrimStart / TrimEnd:去掉首尾空白。用户输入的数据,我建议一律先Trim一下。
重要提醒:字符串比较时,用 string.Equals(a, b, StringComparison.OrdinalIgnoreCase) 可以忽略大小写。别用 == 直接比,容易踩坑。
4.1.2 字符串拼接
拼接方式有好几种。我个人习惯用 $"Hello, {name}" 这种字符串插值,简洁又直观。如果是大量拼接,比如生成日志或构建SQL语句,一定要用 StringBuilder。
// 推荐:字符串插值
string name = "张三";
string message = $"欢迎你,{name}!";
// 大量拼接时用 StringBuilder
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
sb.Append($"第{i}行数据\n");
}
string result = sb.ToString();
小技巧:用 string.IsNullOrWhiteSpace() 判断字符串是否为空或全是空白,比手动判断更安全。
4.2 数组:固定大小的容器
数组是C#里最基础的数据结构。它的大小在创建时就固定了,不能动态增减。你想想看,这就像你买了一个固定格子的收纳盒——每个格子放一种类型的数据。
4.2.1 声明和初始化
// 声明一个int数组,长度为5
int[] numbers = new int[5];
// 声明并初始化
int[] scores = { 90, 85, 78, 92, 88 };
// 多维数组
int[,] matrix = new int[3, 3];
4.2.2 常用操作
- Length:获取数组长度。一维数组用
arr.Length,多维数组用arr.GetLength(0)。 - Array.Sort():排序。默认升序。
- Array.Reverse():反转。
- Array.IndexOf():查找元素索引。
避坑指南:我曾经在遍历数组时,不小心把索引写成了 i <= arr.Length,结果数组越界异常。记住:索引从0开始,最大索引是 Length - 1。
4.3 集合:更灵活的容器
数组用起来有点死板,对吧?集合就灵活多了。C#里最常用的两个集合是 List<T> 和 Dictionary<TKey, TValue>。它们都在 System.Collections.Generic 命名空间下。
4.3.1 List<T>:动态数组
List可以动态增减元素,内部其实是用数组实现的。当容量不够时,它会自动扩容——一般是翻倍。我在项目中遇到过频繁添加大量数据导致性能下降的情况,后来预先设置 Capacity 就好了。
// 创建List
List<string> names = new List<string>();
// 添加元素
names.Add("张三");
names.Add("李四");
// 插入
names.Insert(1, "王五");
// 删除
names.Remove("张三"); // 按值删除
names.RemoveAt(0); // 按索引删除
// 查找
int index = names.IndexOf("李四");
bool exists = names.Contains("王五");
// 遍历
foreach (var name in names)
{
Console.WriteLine(name);
}
4.3.2 Dictionary<TKey, TValue>:键值对
Dictionary是一种哈希表结构,查找速度极快——接近O(1)。我经常用它来做数据缓存或配置映射。比如把用户ID映射到用户对象。
// 创建Dictionary
Dictionary<int, string> students = new Dictionary<int, string>();
// 添加键值对
students.Add(1001, "张三");
students.Add(1002, "李四");
// 取值
string name = students[1001]; // 如果键不存在会抛异常
// 安全取值
if (students.TryGetValue(1003, out string result))
{
Console.WriteLine(result);
}
// 遍历
foreach (var kvp in students)
{
Console.WriteLine($"学号:{kvp.Key},姓名:{kvp.Value}");
}
重要提醒:Dictionary的键必须是唯一的,而且不能为null。取值时尽量用 TryGetValue,避免异常。
4.4 控制流语句:程序的指挥棒
控制流语句决定了代码的执行路径。说白了,就是让程序根据条件做不同的事,或者重复做某件事。
4.4.1 if-else 条件判断
这是最基础的条件语句。我个人习惯把最可能成立的条件放在最前面,这样能减少判断次数。
int score = 85;
if (score >= 90)
{
Console.WriteLine("优秀");
}
else if (score >= 80)
{
Console.WriteLine("良好");
}
else
{
Console.WriteLine("继续努力");
}
4.4.2 switch 语句
当条件分支很多时,switch比if-else更清晰。C# 7.0之后,switch支持模式匹配,功能更强大了。
string day = "周一";
switch (day)
{
case "周一":
case "周二":
case "周三":
case "周四":
case "周五":
Console.WriteLine("工作日");
break;
case "周六":
case "周日":
Console.WriteLine("休息日");
break;
default:
Console.WriteLine("无效输入");
break;
}
小技巧:switch里多个case可以合并执行同一段代码,就像上面那样。另外,别忘了每个case后面加 break,否则会穿透。
4.4.3 for 循环
for循环适合已知循环次数的场景。比如遍历数组或List。
int[] numbers = { 10, 20, 30, 40, 50 };
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
4.4.4 foreach 循环
foreach是C#里我最喜欢的循环方式。它不需要关心索引,直接遍历集合中的每个元素。代码简洁,也不容易出错。
List<string> fruits = new List<string> { "苹果", "香蕉", "橘子" };
foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}
避坑指南:我曾经在foreach循环里尝试删除集合中的元素,结果抛出了 InvalidOperationException。记住:foreach遍历时不能修改集合。如果非要删除,用for循环倒着遍历。
4.4.5 while 循环
while循环适合条件不确定的场景。比如等待用户输入,或者读取文件直到结束。
int count = 0;
while (count < 5)
{
Console.WriteLine($"当前计数:{count}");
count++;
}
4.5 综合示例:学生成绩管理系统
咱们把今天学的知识串起来,写个小例子。这个例子模拟了一个简单的学生成绩管理。
// 用Dictionary存储学生信息:学号 -> 姓名
Dictionary<int, string> students = new Dictionary<int, string>();
students.Add(1001, "张三");
students.Add(1002, "李四");
students.Add(1003, "王五");
// 用List存储成绩
List<int> scores = new List<int> { 85, 92, 78 };
// 遍历输出
for (int i = 0; i < students.Count; i++)
{
var student = students.ElementAt(i);
Console.WriteLine($"学号:{student.Key},姓名:{student.Value},成绩:{scores[i]}");
}
// 计算平均分
int total = 0;
foreach (int score in scores)
{
total += score;
}
double average = total / (double)scores.Count;
Console.WriteLine($"平均分:{average:F2}");
嗯,这一章的内容就这些。字符串、数组、集合、控制流——这些是C#编程的日常工具。你想想看,任何一个Windows桌面应用,都离不开这些基础操作。下一章我们会继续深入,聊聊方法、参数和面向对象编程。到时候见。