簡體   English   中英

在C#中初始化對象的多維數組

[英]Initialize multidimensional array of objects in c#

我只是想知道,是否有更好的方法來初始化對象的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循環並將其替換為單行? 那就太好了。

嵌套for循環通常是初始化2d數組最易讀/可接受的方法。

如果您確實需要單個語句-一種選擇是使用Enumerable.Aggregate (在單個語句中創建/填充數組)和Enumerable.Range + Enumerable.SelectMany (使用如何在c#中使用兩個列表的笛卡爾 Enumerable.SelectMany來創建索引) ):

 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();
}

如果您確實需要“單行初始化”,則將嵌套嵌套for循環重構到方法中(可能是通用的),然后使用“單行”在任意位置調用它。 就像是:

   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;
}

出於好奇,我將更多舊代碼改編為擴展方法,該方法將使用提供的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);
        }
    }
}

感謝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();
            }
        }
    }
}

我認為這是初始化數組的最簡單的一類代碼(為了可讀性而分割成多行):

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM