【问题标题】:Change ref element value with Array.ForEach?使用 Array.ForEach 更改 ref 元素值?
【发布时间】:2014-03-16 09:11:10
【问题描述】:

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

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

这是sn-p:

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

【问题讨论】:

  • 你想要starts.ForEachRef((ref int e) =&gt; e = Math.Max(0, e));这个语法吗?您可以编写一个新类型public delegate void ActionRef&lt;T&gt;(ref T arg);,然后您可以自己编写扩展方法ForEachRef

标签: c# arrays oop foreach extension-methods


【解决方案1】:

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&lt;T&gt; 并改用Count。这仍然适用于数组,但也适用于List&lt;T&gt; 等。)

【讨论】:

  • 您忘记了 this 修饰符来使该方法成为扩展。
【解决方案2】:

您可以通过 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&lt;T&gt;,它使用可分配元素迭代一些容器。

【讨论】:

    【解决方案3】:
    array = array.Select(x => (x < 0) ? 0: x).ToArray();
    

    【讨论】:

    • 那不一样。如果任何其他代码已经引用了同一个数组,他们将看不到差异。而且,这效率很低。
    • @Abhi 这不会修改实际数组,而是创建一个新数组。
    • @Jon: 谢谢你的课 :)
    猜你喜欢
    • 1970-01-01
    • 2017-07-30
    • 2021-05-29
    • 1970-01-01
    • 2010-10-17
    • 2021-11-05
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    相关资源
    最近更新 更多