在二维阵列上实现LINQ样式扩展方法

时间:2012-09-14 15:08:09

标签: c# arrays extension-methods

我有一些与二维网格(数组)一起工作的代码,最后我找到了很多遍历网格中每个项目的例程。

但我认为如果我能使用扩展方法做这种LINQ风格会很好。

这是我到目前为止所尝试的内容:

private static void ForEach(this MyType[,] grid, Action<MyType> action)
{
    for (int row = 0; row < grid.GetUpperBound(0); row++)
        for (int col = 0; col < grid.GetUpperBound(1); col++)
            action(grid[row, col]);
}

1。 Intellisense似乎无法在MyType[3,3]类型的对象上识别此扩展方法。我是否遗漏了为二维数组编写扩展方法的内容?

2。实施这种允许我有条件地设置网格值的模式的推荐方法是什么?使用上面的代码,设置传递的值不会影响原始数组。

修改

好的,在最初在调用它的同一个类中实现这个扩展方法之后,当我将它移动到外部类时,我愚蠢地将它声明为private。我想它在同一个类中不能作为私有方法工作,它显然不能作为外部类中的私有方法。

但仍然希望看到2号的答案。

1 个答案:

答案 0 :(得分:2)

对于第二个问题,Action不起作用,因为它不返回值,因此无法直接更新数组。您可能想要的是Func<MyType,MyType>,它将接受原始值,进行一些处理,并返回一个 new 值,然后ForEach将重新插入到数组中。如果您需要知道行和列,请将其设为Func<MyType, int, int>

作为旁注,我不会将其称为ForEach,因为您正在修改基础集合(ForEach在普通集合中无法做到)。我会称之为UpdateAll或类似的东西。

所以你最终得到的结果是:

public static void UpdateAll(this MyType[,] grid, Func<MyType,MyType> action)
{
    for (int row = grid.GetLowerBound(0); row <= grid.GetUpperBound(0); row++)
        for (int col = grid.GetLowerBound(1); col <= grid.GetUpperBound(1); col++)
            grid[row, col] = action(grid[row, col]);
}

请注意,它使用GetLowerBound并在上限检查中使用<=而不是<