Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# jagged array type declaration in reverse

I just had one of these "What the..." moments. Is the following intended and is there some obscure reasoning behind the "non-natural" declaration of arrays in C#?

int[,][] i; // declares an 2D - array where each element is an int[] !
// you have to use it like this:
i = new int[2,3][];
i[1,2] = new int[0];

I would have expected the other way around. int[,][] declares an 1-dimensional array where each element is a two dimensional array.

Funny though, the type's Name is reversed:

Console.WriteLine(typeof(int[,][]).Name); // prints "Int32[][,]"

Can someone explain this? Is this intentionally? (Using .NET 4.5 under Windows.)

like image 497
Imi Avatar asked Sep 21 '12 14:09

Imi


2 Answers

You can find a lengthy discussion in Eric Lippert's blog Arrays of arrays.

What C# actually does

It’s a mess. No matter which option we choose, something ends up not matching our intuition. Here’s what we actually chose in C#.

First off: option two [It’s a two-dimensional array, each element is a one-dimensional array of ints] is correct. We force you to live with the weirdness entailed by Consequence One; you do not actually make an element type into an array of that type by appending an array specifier. You make it into an array type by prepending the specifier to the list of existing array specifiers. Crazy but true.

The word 'prepending' partly explains your output of the reversed type-name. A CLR type name is not necessarily the same as the C# declaration.

But the more relevant quote is at the bottom:

That all said, multidimensional ragged arrays are almost certainly a bad code smell.

like image 179
Henk Holterman Avatar answered Sep 19 '22 17:09

Henk Holterman


I had the same "what the..." moment the first time I saw new int[5][]; instead of new int[][5];.

EL's (very nice) blog post is dancing around one thing: there's a perfect way to do it for people with a ComSci degree, but no good way to do it for others. If you just follow the grammar, you declare right-to-left, new right-to-left and index left-to-right:

// 1D array of 2D arrays, no special rules needed:
int[,][] N; N=new[,][5]; N[0]=new int[4,4];

But C#'s target audience isn't people with 4-year CS degrees (who have all seen Reverse Polish and love right-to-left.) The trick, IMHO, in understanding C# jagged arrays is that they decided to make special rules for them, when they didn't technically need to.

like image 43
Owen Reynolds Avatar answered Sep 17 '22 17:09

Owen Reynolds