为什么C#中的锯齿状数组以相反的方式定义?

zdi*_*ion 4 c# language-design

假设我有一个名为的类型T.现在让我们说我做了一个类型的数组T,它给了我T[].在代码中,它给出:

var myArray = new T[10];
Run Code Online (Sandbox Code Playgroud)

长度为10.因此,我们可以看到这使得一个包含10个类型项的数组T.如果T是,或任何标准int,这是有效的.但是,假设是一个数组类型,就像或.stringBinaryWriterTint[]string[]

然后,如果我们想要定义一个包含10个type T(int[])项的数组,它应该给出这样的结果:

var myArray = new int[][10];
Run Code Online (Sandbox Code Playgroud)

通过替换Tint[]先前的示例所示.但这会产生语法错误,因为C#中的正确语法是:

var myArray = new int[10][];
Run Code Online (Sandbox Code Playgroud)

如果我们遵循第一个例子的逻辑,那么应该给出一个包含未定义数量的包含10个整数的数组的数组.

这同样适用于锯齿状数组的任何维度:

var myArray = new int[][][10];
Run Code Online (Sandbox Code Playgroud)

是错的,因为语法正确的方法是:

var myArray = new int[10][][];
Run Code Online (Sandbox Code Playgroud)

这不是个人偏好或代码风格的争论,而只是逻辑:当我们定义数组类型数组时,为什么语法不同于我们定义其他任何数组的数组?

Nic*_*ick 6

这样,初始化语法镜像了访问语法.

var myArray = new int[NUM_ROWS][];
...
/* Initialize rows of myArray */
...
var x = myArray[0][5]; /* Should this be row 0, col 5; or row 5, col 0? */
Run Code Online (Sandbox Code Playgroud)

由于索引将从左向右反转,因此myArray[0][5]被解析将是违反直觉的(myArray[5])[0],因此我们将其myArray[0][5]解析为(myArray[0])[5].

这样,在myArray[i][j],i对应于进入二维数组j的索引,并且对应于进入一维数组的索引myArray[i].

现在,i范围可以从0NUM_ROWS-1,所以它是对称的接入语法来初始化var myArray = new int[NUM_ROWS][].这样,左侧括号组仍然对应于二维阵列的长度,右侧括号组仍然对应于一维阵列.

编辑:我看到有人在评论中发布了一篇文章的链接,其中Eric Lippert经历了一个更详细的例子和理由.