使用Array.ForEach更改ref元素值?

时间:2014-03-16 09:11:10

标签: c# arrays oop foreach extension-methods

我正在尝试使用Array.ForEach()扩展方法来遍历数组中已过滤元素的列表,然后修改这些值,不幸的是,这似乎不起作用我猜测因为它没有实际上修改每个元素的参考值。

除了将Array.ForEach()的结果存储到一个单独的数组中然后将该数组克隆到原始数组之外,还有什么办法吗?另外我知道如果我使用for循环,我可以在没有克隆的情况下完成所有这些操作,但如果我能这样做,它会更干净并且代码更少。

以下是片段:

Array.ForEach(Array.FindAll(starts, e => e < 0), e => e = 0);

3 个答案:

答案 0 :(得分:2)

ForEach根本不打算这样做 - 就像你不能用foreach循环一样。

就我个人而言,我只使用for循环 - 它易于阅读和清晰:

for (int i = 0; i < array.Length; i++)
{
    // Alternatively, use Math.Max to pull up any negative values to 0
    if (array[i] < 0)
    {
        array[i] = 0;
    }
}

这很简单 - 任何人都能理解它。

现在你可以编写自己的扩展方法。您可以编写一个来替换满足具有固定值的谓词的所有值,或者您可以编写一个以完全替换所有值...但我不认为它真的值得。作为后者的一个例子:

public static void ReplaceElements<T>(this T[] array,
                                      Func<T, T> replacementFunction)
{
    // TODO: Argument validation
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = replacementFunction(array[i]);
    }
}

然后用:

调用它
starts.ReplaceElements(x => Math.Max(x, 0));

我个人仍然使用for循环。

(您可能会稍微改变上面的内容以使IList<T>更改并使用Count。这仍然适用于数组,但也适用于List<T>等。)

答案 1 :(得分:0)

您可以使用ref和委托来做到这一点。但是,我认为它没有太大的价值。

public delegate void RefAction<T>(ref T value);
public static void ForEachRef<T>(this T[] array, RefAction<T> action)
{
    for (int i = 0; i < array.Length; ++i) action(ref array[i]);
}

您可以按以下方式使用它:

var myArray = new int[];
myArray.ForEachRef((ref int i) => i = whateverYouLike());

从可能性的角度来看,可能存在一个接口IRefEnumerable<T>,该接口使用可分配的元素迭代某些容器。

答案 2 :(得分:-1)

array = array.Select(x => (x < 0) ? 0: x).ToArray();