我只是想知道,有没有更好的方法来初始化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循环并用单行替换它?那太棒了。
答案 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)
感谢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();
}
}
}
}
答案 3 :(得分:0)
我认为这是初始化数组时最简单的单行(分为多行以便于阅读):
var board = Enumerable.Range(0, BoardWidth)
.Select(row => Enumerable.Range(0, BoardHeight)
.Select(value =>new TField())
.ToArray())
.ToArray();