必须用 length 属性获取数组长度,count() 有开销,size 不存在;length 返回总元素数,getlength(dimension) 获取指定维度长度;空数组 length 为 0,需防越界;length 是零开销、跨平台、aot 安全的唯一正确方式。

用 Length 属性获取数组长度,不是 Count() 或 size
数组在 C# 中是固定大小的引用类型,其长度在创建时就确定,且不可变。获取长度必须用实例的 Length 属性,这是唯一正确、高效、零开销的方式。Count() 是 LINQ 扩展方法,作用于 IEnumerable<t></t>,对数组会多一层装箱和迭代开销;size 根本不是 C# 数组的成员,编译直接报错 CS0117。
常见错误场景:
- 误把数组当
List<t></t>用Count属性(List<t></t>有Count,但数组没有) - 在循环条件里写
i ,导致编译失败 - 对多维数组调用
arr.Length后误以为是“行数”,其实返回的是所有元素总数
多维数组的 Length 和 GetLength(int dimension) 区别
Length 对所有数组都返回总元素个数;而 GetLength(dimension) 才能获取指定维度的长度。比如一个 int[3,4] 数组:arr.Length 是 12,arr.GetLength(0) 是 3(第一维行数),arr.GetLength(1) 是 4(第二维列数)。
实际建议:
- 遍历二维数组时,用
arr.GetLength(0)和arr.GetLength(1)分别控制内外层循环,比硬编码更安全 - 不要依赖
Length / 行数算列数——不适用于不规则数组(C# 不支持真正不规则多维数组,但锯齿数组int[][]是例外) - 锯齿数组(
int[][])每个子数组需单独调用subArray.Length,顶层jagged.Length只是子数组个数
数组长度为 0 时的行为:不会抛异常,但要注意边界
空数组(如 new int[0])合法且常见,.Length 返回 0,访问 arr[0] 才会抛 IndexOutOfRangeException。很多逻辑漏洞源于没检查 Length == 0 就直接取首元素或进循环。
典型问题点:
-
foreach遍历空数组完全安全,无需前置判断,但若循环体里有“取第一个”的隐含假设,就会出错 - 用
arr[arr.Length - 1]获取末尾元素时,Length == 0会导致负索引,直接崩溃 - 传给某些 API(如
Span<t>.Create(arr)</t>)时,空数组是允许的,但后续操作仍需自行校验语义有效性
性能与兼容性:为什么不能用反射或 unsafe 拿长度
Length 是数组类型的内置字段(IL 中对应 ldlen 指令),读取是单条 CPU 指令,零分配、零副作用。试图用反射(arr.GetType().GetField("Length"))不仅慢百倍,而且字段名在不同运行时可能非公开;用 unsafe 计算内存偏移更是危险且无必要。
真实约束:
- .NET Framework、.NET Core、.NET 5+ 全部统一支持
Length,无兼容性差异 - 泛型数组(
T[])、原始类型数组(int[])、引用类型数组(string[])行为一致 - AOT 编译(如 .NET Native 或 iOS)下,
Length仍是唯一可靠方式;反射在 AOT 下默认被裁剪
数组长度本身很简单,但多维、空数组、类型混用这几个点,最容易在代码审查或上线后暴露。别想绕开 Length,也别替它加抽象层——它已经是最直接的真相。











