using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int[,] x = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };
foreach (var i in x)
{
foreach (var j in i)
{
Console.WriteLine(j);
}
}
}
}
}
我注意到var i in x
会使数组变平,因此会为第二个foreach
生成以下错误。
错误1 foreach语句无法对'int'类型的变量进行操作 因为'int'不包含'GetEnumerator'的公共定义
是否可以阻止foreach
展平矩形阵列?
答案 0 :(得分:3)
在某种意义上,多维数组是一维数组,它使用维度信息来访问数据,就像它们确实存储在二维中一样。因此,当通过许多方法(例如,从类Array
)和foreach
迭代访问时,它被视为一维数组,因为这是内存中的实际布局。否则,在迭代期间,需要为每一行创建新的一维数组。
您可以尝试按照以下方式实现目标:
int[][]
。IEnumerable<IEnumerable<T>> ByRows<T>(this T[,] array)
,它将创建迭代器,对行进行适当的迭代。显然,行可能是一维数组,也可能是迭代行内容的另一个自定义迭代器。foreach
并使用两个嵌套的for
循环。答案 1 :(得分:2)
如果你有一个锯齿状数组,它将不会这样(即一个声明为int[][]
而不是int[,]
的数组)Foreach旨在枚举每个元素,在2D数组中每个元素都是一个int,而不是一个int数组(尽管静态初始化程序使它看起来像是一个数组数组,但它不是)。如果你想让它按原样运行(使用2D数组),我建议使用传统的for循环而不是foreach。
答案 2 :(得分:0)
问题不在于foreach,而在于从GetEnumerator返回的枚举器的实现。它正在做的是将多维数组视为一个连续的值数组(这就是它在内存中的含义)。
如果您考虑如何实现枚举器以便它为您提供所需的行为,那么它基本上就会枚举IEnumerable。这实际上是一个数组数组。 C#用锯齿状数组表示,或int [] [],正如其他人所提到的那样。
相反,多维数组在C#中建模为一个内存,您可以使用两个索引进行索引。您不能使用一个索引索引多维数组并返回一个数组,就像使用锯齿状数组一样。实际上,如果您尝试使用一个索引索引多维数组,则会出现编译错误。您可以将多维数组实现为单维数组,并自行计算将二维索引转换为单维索引。