C#3维数组定义问题

我的以下代码有编译错误,

错误1无法将类型’TestArray1.Foo [ ,, *]’隐式转换为’TestArray1.Foo [] [] []’C:\ Users \ lma \ Documents \ Visual Studio 2008 \ Projects \ TestArray1 \ TestArray1 \ Program.cs 17 30 TestArray1

有没有人有任何想法? 这是我的整个代码,我使用的是VSTS 2008 + Vista 64位。

namespace TestArray1 { class Foo { } class Program { static void Main(string[] args) { Foo[][][] foos = new Foo[1, 1, 1]; return; } } } 

编辑:版本2.我有另一个版本的代码,但仍然有编译错误。 有任何想法吗?

 Error 1 Invalid rank specifier: expected ',' or ']' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 41 TestArray1 Error 2 Invalid rank specifier: expected ',' or ']' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 44 TestArray1 namespace TestArray1 { class Foo { } class Program { static void Main(string[] args) { Foo[][][] foos = new Foo[1][1][1]; return; } } } 

编辑:版本3.我想我想要一个锯齿状的数组。 在向同伴们学习之后。 这是我的代码修复,它在VSTS 2008中编译良好。我想要的是锯齿状数组,目前我只需要一个元素。 有人可以检查我的代码是否正确实现我的目标吗?

 namespace TestArray1 { class Foo { } class Program { static void Main(string[] args) { Foo[][][] foos = new Foo[1][][]; foos[0] = new Foo[1][]; foos[0][0] = new Foo[1]; foos[0][0][0] = new Foo(); return; } } } 

乔治,提前谢谢

关于代码的第2版 – 遗憾的是,您不能以这种方式指定锯齿状数组。 相反,你需要做:

 Foo[][][] foos = new Foo[1][][]; foos[0] = new Foo[1][]; foos[0][0] = new Foo[1]; 

基本上,你必须分别填充每个数组。 Foo[][][]表示“Foo数组数组的数组”。 像这样的初始化语句只能一次初始化一个数组。 使用矩形数组,您最终只能得到一个(多维)数组,这就是new Foo[1,1,1]有效的原因。

如果这是真正的代码,我建议你至少考虑其他设计决策。 数组数组可能很有用,但您很容易遇到这样的问题。 arrays数组的arrays甚至更糟糕。 可能有更可读的方式来表达您感兴趣的内容。

下定决心:)

你要么:

 Foo[,,] foos = new Foo[1, 1, 1]; 

要么:

 Foo[][][] foos = new Foo[1][1][1]; 

您正在声明一个双嵌套数组(数组数组的数组)并分配一个三维数组。 这两个肯定是不同的。 您可以将声明更改为

 Foo[,,] foos = new Foo[1,1,1] 

如果你想要一个真正的三维数组。 Jagged数组( [][][]种类)不是C#中需要的,比如Java。

最简单的答案是使用

 Foo[,,] foos = new Foo[2, 3, 4]; 

这给你一个三维数组作为2 * 3 * 4 = 24 Foo的连续内存块。

替代方案如下:

 Foo[][][] foos = new Foo[2][][]; for (int a = 0; a < foos.Length; a++) { foos[a] = new Foo[3][]; for (int b = 0; b < foos[a].Length; b++) { foos[a][b] = new Foo [4]; for (int c = 0; c < foos[a][b].Length; c++) foos[a][b][c] = new Foo(); } } 

虽然这种锯齿状(=数组数组)方法稍微有些工作,但使用它实际上更快。 这是由于编译器的缺点导致在访问Foo [,,]情况下的元素时总是进行范围检查,而它能够至少优化使用Foo []中的Length属性的for循环。 [] []场景。

另见这个问题

这两个不同的数组声明创建了非常不同的东西。

让我们看一下更简单的案例:

 Foo[,] twoDimensionArray = new Foo[5,5]; 

此数组有两个维度 – 您可以将其视为一个表。 你需要两个轴才能返回任何东西:

 Foo item = twoDimensionArray[2,3] 

索引总是具有相同的长度 – 在这种情况下为0-4。

锯齿状数组实际上是一个数组数组:

 Foo[][] jaggedArray = new Foo[5][]; jaggedArray[0] = new Foo[2]; jaggedArray[1] = new Foo[4]; ... 

如果您只使用一个轴索引,它将返回一个数组:

 Foo[] oneRow = jaggedArray[3]; 

如果您同时使用这两个,则从子数组中进行选择:

 Foo item = jaggedArray[3][2]; //would be the same as: Foo item = oneRow[2]; 

这些子arrays中的每一个可以具有不同的长度,或甚至不被填充。

取决于你是否希望它们是锯齿状的:

 //makes a 5 by 4 by 3 array: string[,,] foos = new string[5,4,3]; 

http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx

哦,这里是初始化值:

  char[, ,] blah = new char[2, 2, 2] { {{ '1', '2' }, { '3', '4' }}, {{ '5', '6' }, { '7', '8' }} }; 

请注意,这不起作用:

 Foo[][][] foos = new Foo[1][1][1]; 

因为您使用的是锯齿状数组语法,它不允许您定义嵌套数组的大小。 而是使用这样做:

 Foo[,,] foos = new Foo[1][1][1]; //1 by 1 by 1 

或这个

 Foo[][][] foos = new Foo[1][][]; //1 array allowing two nested levels of jagged arrays foos[0] = new Foo[1]; //for the first element, create a new array nested in it foos[0][0] = new Foo[1]; //create a third level new array nested in it 

如果它意味着什么,只为C#声明:

 int[,,] ary = new int[,,] { { { 111, 112 }, { 121, 122 }, { 131, 132 } } , { { 211, 212 }, { 221, 222 }, { 231, 232 } } , { { 311, 312 }, { 321, 322 }, { 331, 332 } } , { { 411, 412 }, { 421, 422 }, { 431, 432 } } }; 

数组初始化

 int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } } 

source: 多维数组(C#编程指南)