【问题标题】:Creating an array of two-dimensional arrays in C#在 C# 中创建一个二维数组
【发布时间】:2016-04-23 10:25:04
【问题描述】:

我只是想创建一个二维数组来存储坐标点。

所以我想要一个数组,其中每个索引返回一个二维数组,我将用作xy

这是我尝试过的:

waypoints = new int[4][,]    {
        {{0},{6, 0}},
        {{1},{1, 1}},
        {{2},{1, 5}},
        {{3},{6, 5}}
    };

我意识到这可能看起来很愚蠢,但我尝试在 Google 上查找它,但没有得到任何好的结果。

它给出了一个错误:

"错误 CS0623: 数组初始化器只能用于变量或 字段初始化器。尝试使用新表达式“

我也试过这样做:

waypoints = new int[4][,] {
        new int[,] {6, 0},
        new int[,] {1, 1},
        new int[,] {1, 5},
        new int[,] {6, 5}
        };

这给出了一个错误:

“错误 CS0846:需要嵌套数组初始化程序”

【问题讨论】:

  • 为什么不创建Vector2 结构或类似的列表?从长远来看,它可能更容易使用并且更简单。
  • @rhughes:更不用说更好的引用局部性(当前处理器中 Ln 缓存的一个重要考虑因素)和减少垃圾收集(因为 数组 是一个对象,而结构是不是)。

标签: c# arrays multidimensional-array initialization initializer


【解决方案1】:

我可能误解了这个问题,但是您的数组中的维度不是太远了吗?这与建议使用 Point 或 Vector 类的人的观点相同。如果每个数组只存储一个点(它可能不是,我可能只是假设),你不需要 3 维。您可以有一个常规数组的数组,并将索引 0 用于 x 坐标,将索引 1 用于 y 坐标。

在我看来,您正在创建一个完整的第 3 维,其中每个数组的大小为 1,这将更容易可视化为 2d 数组。虽然看起来您将数组用作一种键值对,但索引本身可以用作键吗?无论如何,它们似乎每次都在增加。

【讨论】:

    【解决方案2】:

    在初始声明中还需要一个大括号集{}

    var waypoints = new int[4][,]   {
        new int[,] {{6}, {0}},
        new int[,] {{1}, {1}},
        new int[,] {{1}, {5}},
        new int[,] {{6}, {5}}
    };
    

    这是因为对于这样的二维数组,数组中的每个元素都被视为一个数组进行初始化(尽管它通常用于数组的每个元素,例如val[0,0] = 4;)。

    编辑(根据 cmets 的反馈):

    对比int[][](称为jagged array,即:数组成员可以是different size的数组),int[,]fixed dimension是一个二维数组。两者都是存储数组的数组,因此数组的每个元素都是一个数组。这解释了为什么需要在上面的初始化中放置另一个大括号。

    这样的二维数组,当初始化不同时,会产生不同的维度(因此有多种初始化方式):

    int[,] val = new int[,] { { 6 }, { 0 } }; //resulting in int[2,1]
    int[,] val = new int[,] { { 6, 0 } }; //resulting in int[1,2]
    

    无论哪种方式,都需要额外的一组大括号

    对于jagged array 和多维、固定大小的数组之间的区别,therealready plenty good explanations/benchmarking available online 来自知名来源。而且我知道,除了 OP 的兴趣之外,我提供更多有关它的信息并不重要。 (因此,这个答案的范围最初只是针对失败的初始化)。

    据了解,该解决方案不适用于存储坐标点(如 OP 所做的那样)。上面的解释是为了解释为什么他的初始化不起作用,而不是为存储坐标点提供最佳解决方案。至于存储坐标点,System.Drawingstruct 中的Point 会更合适(在评论中建议)。

    使用 2D 数组来表示 2D 中的单个点 Cartesian coordinate 是“矫枉过正”,因为 1D 数组已经能够存储计算机允许的尽可能多的数字,远远超过存储点所需的两个数字笛卡尔坐标系。

    【讨论】:

    • 谢谢!如果你能解释为什么会这样,我会很高兴:)
    • 我相信这是微软在 MSDN 中最好的解释:social.msdn.microsoft.com/Forums/en-US/… PS:但是如果你想存储点,使用Pointclass 存储它可能是值得的
    • 我相信 new int[,] {{6,0}} 就足够了,并且可以说更具可读性
    • @aardila 是的,因为它是二维的,所以这是 truly overkill。我们甚至可能只需要int[](我们已经可以存储两个以上的数字)。我的示例只是表明需要另一组大括号(用于二维数组)。但是对于使用几何点,我认为Point 效果最好 - 请参阅其他答案。
    【解决方案3】:

    数组是二维的,大小未知,初始化器可以定义各种大小的数组:

            var waypoints = new int[4][,]   {
                    new int[,] { {1, 2, 6}, {3, 4, 5} }, // two rows, 3 columns
                    new int[,] { {1, 1}, {1, 2} } , // 2 x 2
                    new int[,] { {1, 5} }, // 1 x 2
                    new int[,] { {6, 5} }
                    };
    

    【讨论】:

      【解决方案4】:

      对此有一个简单的答案。使用“System.Drawing.Point”类的实例。创建一个“点”数组来存储坐标。创建数组:

      Point[] points = new Point[4];
      

      并为数组赋值(例如在位置 0)使用以下代码。

      points[0] = new Point(xvalue,yvalue);//Where "xvalue" and "yvalue" are integer variables.
      

      并从点类的实例中获取 X 和 Y 值。使用下面的代码。

      int xvalue = points[0].X;
      
      int yvalue = points[0].Y;
      

      附:您可以使用这些点将位置分配给控件,但这是另一回事^_^

      【讨论】:

      • 谢谢,我查一下!
      猜你喜欢
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多