十六、数组(Arrays)
✅ 第16章:数组与集合(Arrays and Collections)
📘 一、数组初始化与类型系统
✅ 所有数组都是 System.Array 的子类
int[] nums = new int[] { 1, 2, 3 };
Console.WriteLine(nums.GetType()); // System.Int32[]
Console.WriteLine(nums is Array); // true
- 数组在 CLR 中是 一等对象,具有完整的元数据(类型、维度、大小)
- 实现了
IEnumerable、ICollection、IList接口(非泛型)
🧱 二、数组的装箱陷阱:协变性问题
string[] names = new string[3];
object[] objs = names; // ✅ 协变允许
objs[0] = 123; // ❌ 运行时抛出 ArrayTypeMismatchException
✅ C# 允许引用类型数组协变,但存在类型安全问题
➡️ 推荐:用泛型集合替代数组协变场景
🚀 三、数组与泛型集合对比
| 特性 | 数组 (T[]) |
List<T> |
|---|---|---|
| 固定大小 | ✅ 是 | ❌ 自动扩展 |
| 速度 | ✅ 极快 | 稍慢,带边界检查 |
| 安全性 | ✅ 高 | ✅(泛型安全) |
| 动态增删 | ❌ 不支持 | ✅ 支持 |
结论:数组适合底层高性能密集数据场景;集合适合动态操作
📌 四、数组作为参数传递与返回
- 数组是引用类型:传递的是引用地址(但不会修改引用本身)
void Fill(int[] arr) {
arr[0] = 100; // ✅ 修改内容
arr = new int[5]; // ❌ 不影响原数组
}
🔁 五、数组转型与接口转换
int[] arr = {1,2,3};
IEnumerable<int> seq = arr; // ✅ 支持
IList list = arr; // ✅ 支持非泛型接口
➡️ 因为 System.Array 实现了很多接口,易于与 LINQ、foreach 兼容
🌐 六、非零下限数组(不推荐使用)
Array arr = Array.CreateInstance(typeof(int), new int[] { 3 }, new int[] { 1 });
创建下限为 1 的数组 [1,2,3],但不兼容大部分 C# 语法与优化。
➡️ ⚠️ 性能差、兼容性差,不建议在实际项目中使用
🧠 七、数组内部工作机制(CLR视角)
✅ 数组头部结构(内存布局):
+-------------------------+
| Method Table Ptr | ← 类型元数据
| Length (Int32) | ← 数组元素数量
| [Element 0] |
| [Element 1] |
| ... |
+-------------------------+
- 元数据指向类型信息(类型名、元素类型)
- 紧跟数组长度字段(避免越界)
- 然后是连续元素块
⚙️ 八、不安全数组访问与固定大小数组
unsafe {
fixed (int* p = myArray) {
*(p + 1) = 42;
}
}
fixed禁止 GC 移动数组- 可用于原生交互 / 性能极端优化(如图像处理)
📊 Mermaid 图:数组行为概览
graph LR
A[定义数组] --> B[引用类型 System.Array]
B --> C[实现 IEnumerable/IList]
C --> D[传递到方法中]
B --> E[存储元素 + 长度]
E --> F[支持协变(仅引用类型)]
🧪 面试题
1️⃣ 为什么数组协变会导致运行时异常?
✅ 因为可以将 string[] 赋值给 object[],但 object[] 允许写入任何类型,破坏类型安全。
2️⃣ 创建数组后能改变其大小吗?
❌ 不可以。数组大小固定,只能重新创建新数组并复制内容。
3️⃣ 多维数组 vs 交错数组(区别?)
- 多维数组是
[,],内存连续,占用空间大 - 交错数组是
[][],每行可不同长,更灵活、兼容
4️⃣ 为什么数组不能作为协变泛型?
✅ 协变泛型需要只读行为,数组是可变集合,不满足约束。
5️⃣ 使用 Array.Copy() 与 Buffer.BlockCopy() 有何不同?
✅ Array.Copy() 是类型安全的;BlockCopy() 是字节级别的,适合低层数据处理(比如结构体序列化)
九、BlockCopy和Span
[[BlockCopy]]
✅ 总结速查表
| 特性 | 说明 |
|---|---|
| 是引用类型 | 数组存储在堆上,参数传递为引用 |
| 支持协变 | 仅限引用类型,存在类型风险 |
| 多接口支持 | 可转为 IEnumerable, IList 等 |
| 多维 vs 交错 | 多维占内存、慢;交错灵活 |
| 不安全访问 | 用于极限性能优化场景 |
| 非零下限 | 支持,但不推荐使用 |
点赞鼓励下,(づ ̄3 ̄)づ╭❤~
作者:世纪末的魔术师
出处:https://www.cnblogs.com/Firepad-magic/
Unity最受欢迎插件推荐:点击查看
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号