是否可以防止 foreach 展平矩形数组

本文关键字:数组 foreach 是否 | 更新日期: 2023-09-27 18:30:16

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扁平化矩形阵列?

是否可以防止 foreach 展平矩形数组

从某种意义上说,多维数组是一个一维数组,它使用维度信息来访问数据,就好像它们真的存储在二维中一样。正因为如此,当通过许多方法(例如从类Array)访问时,foreach迭代,它被视为一维数组,因为这是内存中的实际布局。否则,在迭代期间,需要为每一行创建新的一维数组。

您可以尝试执行以下操作来实现您想要的:

  1. 使用交错数组而不是多维数组:int[][] .
  2. 创建扩展方法IEnumerable<IEnumerable<T>> ByRows<T>(this T[,] array),该方法将创建对行执行正确迭代的迭代器。显然,行要么是一维数组,要么是另一个迭代行内容的自定义迭代器。
  3. 完全跳过foreach并使用两个嵌套for循环。
如果你

有一个交错数组,它就不会以这种方式运行(即声明为int[][]而不是int[,]的数组) Foreach 旨在枚举每个元素,在 2D 数组中,每个元素都是 int,而不是 int 数组(尽管静态初始值设定项使其看起来像是数组数组,但事实并非如此)。如果你想让它按原样工作(使用 2D 数组),我建议使用传统的 for 循环而不是 foreach。

问题不在于foreach,而在于从GetEnumerator返回的枚举器的实现。它所做的是将多维数组视为一个连续的值数组(这就是它在内存中的内容)。

如果您考虑如何实现枚举器,以便它为您提供所需的行为,那么它基本上是通过 IEnumerable 进行枚举。这实际上是一个数组数组。C# 用交错数组或 int[][] 表示这一点,正如其他人所提到的。

相反,多维数组在 C# 中建模为使用两个索引编制索引的内存块。您不能像使用交错数组那样,用一个索引索引多维数组并返回一个数组。实际上,如果您尝试使用一个索引为多维数组编制索引,则会出现编译错误。您可以将多维数组实现为单维数组,并自己进行数学运算以将二维索引转换为单维索引。