C# 对二维数组中的每个元素执行操作

C# 对二维数组中的每个元素执行操作,c#,lambda,C#,Lambda,我目前正在制作一个游戏,背景由一个2D的瓷砖阵列表示。Tile是一个相对简单的类,包含图形和可遍历性信息。在我的代码中,我发现自己经常想做类似于以下的事情: for (int x = 0; x < TileMap.GetLength(0); x++) { for (int y = 0; y < TileMap.GetLength(1); y++) { // do something } } 但这不管用。我可以在扩展方法或lambda表达式中设

我目前正在制作一个游戏,背景由一个2D的瓷砖阵列表示。Tile是一个相对简单的类,包含图形和可遍历性信息。在我的代码中,我发现自己经常想做类似于以下的事情:

for (int x = 0; x < TileMap.GetLength(0); x++)
{
    for (int y = 0; y < TileMap.GetLength(1); y++)
    {
        // do something
    }
}

但这不管用。我可以在扩展方法或lambda表达式中设置一个断点,并观察它在每次迭代中被命中,但TileMap中的实际Tile保持不变。对于上面的示例,如果之前的所有平铺都为null,那么它们仍然为null。我做错什么了吗?有没有更好的方法来做我想做的事

根据您的描述,听起来您希望能够修改数组中的元素本身,而不仅仅是它引用的对象(或它存储的值…不清楚
Tile
class
还是
struct
)。当然,调用
操作
委托,只是将值从数组传递给方法,而不是数组元素的引用。在这种情况下,委托无法修改数组本身

解决此问题的一种方法是通过引用而不是默认值传递数组的元素。内置委托类型不支持按引用传递参数。但您可以声明自己的委托(有关更多详细信息,请参阅):

另一种方法(IMHO可能更简洁)是,如果需要,让动作委托返回一个新值:

public static void PerformAction(this Tile[,] tileMap, Func<Tile, Tile> action)
{
    for (int x = 0; x < tileMap.GetLength(0); x++)
    {
        for (int y = 0; y < tileMap.GetLength(1); y++)
        {
            tileMap[x, y] = action(tileMap[x, y]);
        }
    }
}

您只是在修改参数的值。如果希望能够修改实际引用,则需要添加
ref
修饰符。
TileMap.PerformAction(t => t = new Tile());
delegate void ActionRef<T>(ref T t);
public static void PerformAction(this Tile[,] tileMap, ActionRef<Tile> action)
{
    for (int x = 0; x < tileMap.GetLength(0); x++)
    {
        for (int y = 0; y < tileMap.GetLength(1); y++)
        {
            action(ref tileMap[x, y]);
        }
    }
}
void MyActionMethod(ref Tile tile)
{
    // do something to tile
}
public static void PerformAction(this Tile[,] tileMap, Func<Tile, Tile> action)
{
    for (int x = 0; x < tileMap.GetLength(0); x++)
    {
        for (int y = 0; y < tileMap.GetLength(1); y++)
        {
            tileMap[x, y] = action(tileMap[x, y]);
        }
    }
}
Tile MyActionMethod(Tile tile)
{
    // do something to tile

    return tile;
}