[英]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);
}
}
}
感謝MarcinJuraszek和Alexei 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.