在 C# 中获取单维和多维数组的长度
介绍
在本指南中,我们将研究如何使用 Length 关键字获取一维数组的长度以及如何检索具有多维的数组的长度。
获取一维数组的长度
在这个例子中,我们创建一个简单的控制台应用程序,它分配一个足够大的数组来容纳 1000 个整数,然后写出数组的长度。
using System;
namespace Pluralsight.ObtainingArrayLength.SingleDimension
{
class Program
{
static void Main(string[] args)
{
int[] myIntegers = new int[1000];
int length = myIntegers.Length;
Console.WriteLine($"The length of myIntegers is {length}");
}
}
}
这里我们最感兴趣的是读取myIntegers.Length 的那一行。编译后,它将转换为以下中间语言 (IL) 代码:
ldloc.0 // myIntegers
ldlen
conv.i4
stloc.1 // length
如果我们分解一下,就会发现它其实非常简单。第一行将变量myIntegers放在称为评估堆栈的顶部。然后,.NET 使用ldlen加载此数组的长度,然后使用conv.i4将其转换为整数。最后使用stloc将其存储以供使用。
为了准确理解 C# 的作用,对 IL 有一个基本的了解是非常重要的。这告诉我们编译器会产生什么。
当我们构建并运行应用程序时,我们应该得到以下输出:myIntegers 的长度为 1000
获取多维数组的长度
现在我们知道如何检索单维数组的长度,让我们看看如何在多维数组中执行相同的操作。在此示例中,我们将编写一个应用程序,分配一个 20x30 数字的网格,然后检索并显示长度。
using System;
namespace Pluralsight.ObtainingArrayLength.MultiDimensions
{
class Program
{
static void Main(string[] args)
{
int[,] myIntegers = new int[20, 30];
int length = myIntegers.Length;
Console.WriteLine($"In two dimensions, the total length is {length}");
}
}
}
当我们构建并运行此示例时,控制台中会输出以下内容:在二维中,总长度为 600我们在这里看到的是,长度在本例中是指数组中所有维度的长度;因此,这里的长度是 20x30。更有趣的是 IL 发生了什么。获取一维长度的 IL 很简单,但对于多维来说,它看起来大不相同。
ldloc.0 // myIntegers
callvirt instance int32 [System.Runtime]System.Array::get_Length()
stloc.1 // length
callvirt行调用Array.get_Length,然后将结果值放入评估堆栈以供使用。这告诉我们单维数组和多维数组之间的行为存在明显差异。
我们可能会尝试通过以下方式来获取特定维度的长度:
int length = myIntegers[0].Length;
如果我们输入该代码并尝试编译,我们会发现它无法编译并出现以下警告:[] 内的索引数量错误;预期为 2
我们知道我们的数组有两个维度,因此尝试获取第二维数组似乎是合理的,如下所示:
int length = myIntegers[0,0].Length;
如果我们尝试编译此代码,我们将收到以下编译错误,因为myIntegers[0,0]是值本身:“int”不包含“Length”的定义,并且找不到接受类型“int”的第一个参数的扩展方法“Length”(您是否缺少 using 指令或程序集引用?)
现在我们知道无法使用Length获取多维数组中单个维度的长度,那么我们实际上如何获取长度呢?
幸运的是,.NET 提供了一种有用的方法,称为GetLength,它接受我们想要检索的维度。
维度从零开始,因此获取第一个维度使用 0,获取第二个维度使用 1。
使用GetLength我们的代码如下所示:
using System;
namespace Pluralsight.ObtainingArrayLength.MultiDimensions
{
class Program
{
static void Main(string[] args)
{
int[,] myIntegers = new int[20, 30];
int firstDimension = myIntegers.GetLength(0);
int secondDimension = myIntegers.GetLength(1);
Console.WriteLine($"The total length is {firstDimension}x{secondDimension}");
}
}
}
现在,如果我们编译并运行该程序,我们将正确打印出每个维度的长度:总长度为 20x30
长度真的是长度吗?
完全可以创建不从零开始的数组。问题是,Length真的会返回数组的长度吗?还是它只是返回我们输入的值减去数组的起始点(称为下限)?
假设我们有一个包含五个元素的数组,其下限为八。
Array values = Array.CreateInstance(typeof(int), new int[] { 5 }, new int[] { 8 });
Console.WriteLine($"Our none zero indexed array has a length of {values.Length}");
如果我们运行这个程序,代码仍然会告诉我们长度为 5 个条目。无论数组的下限值是多少,长度始终是数组的实际长度。
长度总是有效吗?
有两种情况我们无法使用 Length 获取长度。第一种情况是数组中的项目多于整数可以容纳的数量。在这种情况下,我们可以使用LongLength和相关的GetLongLength方法获取 long 长度。
第二种情况是我们尝试获取未初始化数组的长度。当我们尝试对未初始化数组调用Length时,应用程序会抛出以下异常:System.NullReferenceException:'对象引用未设置为对象的实例'
每当我们看到这个错误时,就意味着我们实际上还没有实例化我们正在查看的东西。在尝试对对象执行任何操作之前,确保已创建该对象是一种很好的做法。
结论
我们研究了如何使用Length来获取一维数组的长度,以及如何使用GetLength来检索多维数组中各个维的长度。
我们简要讨论了如何使用LongLength或GetLongLength来检索无法在int中保存的数组的长度。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~