foreach能遍历所有一维数组(如int[]、string[]),因其隐式实现IEnumerable;多维数组仅实现非泛型IEnumerable,遍历时元素为object类型,需手动转换且无类型安全。

foreach 能不能遍历所有 C# 数组
能,但前提是数组类型实现了 IEnumerable 或其泛型变体 IEnumerable。C# 中所有一维数组(如 int[]、string[]、MyClass[])都隐式实现 IEnumerable,所以 foreach 可直接用;但多维数组(如 int[,] )只实现非泛型 IEnumerable,foreach 虽能编译通过,但迭代出的元素类型是 object,需手动转换,容易出错且无类型安全。
foreach 遍历一维数组的正确写法
必须确保变量类型与数组元素类型一致,否则编译失败。编译器会自动推导 var 的实际类型,但显式声明更清晰、可读性更强。
string[] names = { "Alice", "Bob", "Charlie" };
foreach (string name in names)
{
Console.WriteLine(name);
}
// 等价写法(推荐显式类型,尤其在团队协作或后期维护时)
foreach (var name in names) // var → string
{
Console.WriteLine(name);
}
- 不能写成
foreach (int x in names):类型不匹配,编译报错Cannot convert type 'string' to 'int' - 不能在循环体内修改循环变量本身(如
name = "New"),这只会改局部副本,不影响原数组 - 数组长度为 0 时,
foreach自动跳过,不会抛异常
为什么 foreach 比 for 更安全但更受限
foreach 底层调用数组的枚举器(GetEnumerator()),它封装了索引逻辑和边界检查,因此不会出现 IndexOutOfRangeException;但它禁止在遍历过程中修改被遍历的数组——哪怕只是重新赋值某个元素,也会触发运行时异常 InvalidOperationException: Collection was modified。
- ✅ 安全点:无需关心
Length、下标越界、空引用(只要数组本身不为null) - ❌ 限制点:无法获取当前索引,不能反向遍历,不能跳过元素,不能在循环中增删/重赋整个数组
- ⚠️ 注意:如果数组变量本身被重新赋值(如
names = new string[0];),不算“修改集合”,不会触发异常;但修改数组内容(如names[0] = "X";)会触发异常
遇到 null 数组怎么办
foreach 本身不处理 null,直接对 null 数组调用会抛出 NullReferenceException。必须提前判空,没有捷径。
string[] data = GetData(); // 可能返回 null
if (data != null)
{
foreach (string item in data)
{
Console.WriteLine(item);
}
}
else
{
Console.WriteLine("Array is null");
}别指望 foreach (var x in data ?? new string[0]) 来“兜底”——虽然语法合法,但掩盖了上游可能的逻辑缺陷;null 往往意味着数据缺失或初始化失败,该查原因,不该静默绕过。









