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

本文关键字:元素 ref 更改 Array ForEach 使用 | 更新日期: 2023-09-27 17:50:38

我试图使用Array.ForEach()扩展方法来循环从数组中过滤元素的列表,然后修改这些值,不幸的是,这似乎不工作我猜,因为它实际上并没有修改每个元素的参考值。

除了将Array.ForEach()的结果存储到单独的数组中,然后将该数组克隆到原始数组之外,是否有任何方法可以做到这一点?我也知道,如果我使用for循环,我显然可以在没有克隆的情况下完成所有这些,但如果我可以这样做,它将更干净,代码将更少。

下面是代码片段:
Array.ForEach(Array.FindAll(starts, e => e < 0), e => e = 0);

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

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>等)

您可以使用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>,它迭代某些具有可赋值元素的容器。

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