C# Array 类(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在编程的世界中,数据结构如同构建高楼的基石,而 C# Array 类 则是最基础且不可或缺的容器之一。无论是存储一组学生成绩、记录用户登录时间,还是实现复杂的算法逻辑,数组都以其简洁高效的特点成为开发者手中的利器。
对于编程初学者而言,理解数组的特性与用法是迈向进阶的必经之路;而对中级开发者来说,深入掌握其底层原理与最佳实践,能够显著提升代码的健壮性和性能。本文将从 C# Array 类 的核心概念出发,结合实际案例与代码示例,逐步揭开数组的“神秘面纱”。
一、数组的核心概念:从仓库到数据容器
想象一个仓库货架:每个货位都有固定编号,存放特定物品。C# Array 类 的工作方式与之类似——它提供了一组连续的内存空间,每个位置(即“索引”)存储一个相同类型的元素。
1.1 数组的定义与特性
- 固定长度:数组一旦创建,其大小无法动态调整。例如,声明
int[5]
后,只能存储 5 个整数。 - 同类型元素:所有元素必须是相同类型,例如
string[]
数组只能存放字符串。 - 连续内存存储:数组元素在内存中是连续排列的,这使得随机访问(通过索引)非常高效。
1.2 数组的声明与初始化
声明方式
// 声明一个整型数组,但未分配内存
int[] scores;
// 直接初始化并赋值
string[] names = new string[] { "Alice", "Bob", "Charlie" };
初始化语法糖(Syntactic Sugar)
// 简化写法
int[] numbers = { 10, 20, 30, 40 };
特殊场景:空数组的使用
// 声明一个长度为0的数组
bool[] flags = new bool[0];
二、数组的操作:访问、遍历与修改
2.1 索引访问:像查字典一样定位元素
数组的索引从 0 开始,这类似于书籍页码的起始方式。通过索引可以直接读取或修改元素:
int[] temperatures = { 23, 25, 22, 26 };
Console.WriteLine(temperatures[1]); // 输出 25
temperatures[3] = 27; // 修改第四个元素
注意事项:
- 越界访问(如
temperatures[4]
)会导致IndexOutOfRangeException
。 - 可通过
Length
属性获取数组长度:Console.WriteLine($"数组长度:{temperatures.Length}"); // 输出 4
2.2 遍历数组:循环的多种实现
使用 for
循环
for (int i = 0; i < temperatures.Length; i++)
{
Console.Write(temperatures[i] + " ");
}
// 输出:23 25 22 27
使用 foreach
循环(推荐用于只读场景)
foreach (int temp in temperatures)
{
Console.Write(temp + " ");
}
结合 System.Linq
的扩展方法
using System.Linq;
int sum = temperatures.Sum(); // 计算总和
int max = temperatures.Max(); // 获取最大值
三、多维数组与交错数组:扩展数据的维度
3.1 多维数组(Multidimensional Arrays)
多维数组类似于表格或矩阵,其元素通过多个索引访问:
// 声明一个 2x3 的二维数组
int[,] matrix = new int[2, 3]
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
Console.WriteLine(matrix[1, 2]); // 输出 6
3.2 交错数组(Jagged Arrays)
交错数组是“数组的数组”,允许每一维的长度不同:
// 声明一个二维交错数组
int[][] jagged = new int[2][]
{
new int[] { 10, 20 },
new int[] { 30, 40, 50 }
};
Console.WriteLine(jagged[1][2]); // 输出 50
四、数组的局限性与替代方案
4.1 数组的不足
尽管 C# Array 类 效率高,但它存在以下限制:
- 不可变长度:无法在运行时动态扩容或缩容。
- 类型严格性:所有元素必须是相同类型(泛型数组如
T[]
可部分缓解此问题)。
4.2 替代方案:List<T>
的优势
List<T>
是动态数组的典型实现,支持增删操作且兼容泛型:
List<int> dynamicNumbers = new List<int>();
dynamicNumbers.Add(100);
dynamicNumbers.RemoveAt(0); // 移除第一个元素
五、实战案例:学生成绩管理系统
5.1 需求分析
设计一个简单的系统,记录学生的姓名、数学和语文成绩,并计算平均分。
5.2 代码实现
class Student
{
public string Name { get; set; }
public int MathScore { get; set; }
public int ChineseScore { get; set; }
}
class Program
{
static void Main()
{
// 初始化学生数组
Student[] students = new Student[3]
{
new Student { Name = "Alice", MathScore = 85, ChineseScore = 90 },
new Student { Name = "Bob", MathScore = 78, ChineseScore = 88 },
new Student { Name = "Charlie", MathScore = 92, ChineseScore = 85 }
};
// 计算平均分
foreach (var student in students)
{
double average = (student.MathScore + student.ChineseScore) / 2.0;
Console.WriteLine($"{student.Name} 的平均分:{average:F1}");
}
}
}
六、性能优化与最佳实践
6.1 预分配内存提升性能
避免频繁扩容时,可预先设置数组大小:
int capacity = 1000;
string[] items = new string[capacity];
6.2 避免不必要的数组拷贝
使用 Span<T>
或 ReadOnlySpan<T>
处理内存块,减少内存开销:
Span<int> span = stackalloc int[5] { 1, 2, 3, 4, 5 };
结论
C# Array 类 是编程中不可或缺的基础工具,其简洁性与高效性使其成为处理固定规模数据的首选。通过本文的讲解,读者应能掌握数组的声明、操作、多维扩展及替代方案的选择逻辑。
在实际开发中,开发者需根据场景灵活选择数据结构:若数据规模固定且需频繁随机访问,数组是理想选择;若需动态调整大小,则 List<T>
更为合适。随着对 C# Array 类 的深入理解,开发者将能编写出更高效、可维护的代码,为更复杂的系统设计打下坚实基础。
(全文约 1600 字)