在c#中初始化多维对象数组

时间:2015-08-23 01:52:15

标签: c# .net arrays multidimensional-array

我只是想知道,有没有更好的方法来初始化c#多维对象数组(引用类型)。

这是我的代码:

Board = new Field[BoardHeight, BoardWidth];

for (int i = 0; i < BoardHeight; i++)
{
    for (int j = 0; j < BoardWidth; j++)
    {
        Board[i, j] = new Field();
    }
}

如果我可以摆脱for / for循环并用单行替换它?那太棒了。

4 个答案:

答案 0 :(得分:3)

嵌套for循环通常是最可读/可接受的初始化2d数组的方法。

如果你真的需要单个语句 - 一个选项是使用Enumerable.Aggregate(在单个语句中创建/填充数组)和Enumerable.Range + Enumerable.SelectMany(使用{{3创建索引) }}):

 Board = Enumerable.Range(0, BoardHeight)
         .SelectMany(x => Enumerable.Range(0, BoardWidth), (row,col)=>new {row,col})
         .Aggregate(new Field[BoardHeight, BoardWidth],
             (board, position)=> 
               {
                   board[position.row,position.col] = new Field(); 
                   return board;
               });

(此代码的可读性可供讨论)

更实际的解决方案:

for (var i = 0; i < BoardHeight* BoardWidth; i++) 
{
    Board[i / BoardWidth, i % BoardWidth] = new Field();
}

如果你真的需要&#34;单线初始化&#34; - 重构嵌套for循环到方法(可能是通用的)并在任何地方调用它&#34;单行&#34;。类似的东西:

   public TField[,] InitializeArray<TField>(
      int BoardHeight, int BoardWidth) where TField:new()
   {
        var Board = new TField[BoardHeight, BoardWidth];

        for (int i = 0; i < BoardHeight; i++)
        {
            for (int j = 0; j < BoardWidth; j++)
            {
                Board[i, j] = new TField();
            }
        }
        return Board;
}

答案 1 :(得分:0)

为了好奇而不是其他任何事情,我将一些旧代码改编成一个扩展方法,该方法将使用提供的Func的结果初始化任意等级数组的每个成员。您可以像这样使用它(使用2D,3D,无论D阵列):

var board = new Foo[10, 20];
board.Fill(() => new Foo());

这是扩展方法:

static class Extensions
{
    public static void Fill(this Array arr, Func<object> gen)
    {
        // Get the dimensions of the array
        var dims = Enumerable.Range(0, arr.Rank)
            .Select(arr.GetLength)
            .ToArray();

        Func<int, int, int> product = (i1, i2) => i1 * i2;

        for (var i = 0; i < arr.Length; i++)
        {
            var indices = dims.Select((d, n) => (i/dims.Take(n).Aggregate(1, product))%d).ToArray();
            arr.SetValue(gen(), indices);
        }
    }
}

答案 2 :(得分:0)

感谢MarcinJuraszekAlexei Levenkov建议我得出了这个答案。从技术上讲,这不是一个单一的声明(总而言之),但如果你隐藏扩展方法;-)它看起来会很干净:

Board = new Field[BoardHeight, BoardWidth];
Board.Init();

隐藏此处:

public static class MyExtensions
{
    public static void Init<T>(this T[,] board) where T : new()
    {
        for (int i = 0; i < board.GetLength(0); i++)
        {
            for (int j = 0; j < board.GetLength(1); j++)
            {
                board[i,j] = new T();
            }
        }
    }
}

答案 3 :(得分:0)

我认为这是初始化数组时最简单的单行(分为多行以便于阅读):

var board = Enumerable.Range(0, BoardWidth)
    .Select(row => Enumerable.Range(0, BoardHeight)
        .Select(value =>new TField())
        .ToArray())
    .ToArray();