更改List <T> .ForEach ForEach方法中的元素值

Jon*_*Jon 27 c# linq c#-3.0

我有以下代码:

newsplit.ToList().ForEach(x => x = "WW");
Run Code Online (Sandbox Code Playgroud)

我希望列表中的所有元素现在都是"WW",但它们仍然是原始值.怎么会?我该怎么办?

jas*_*son 38

假设这newsplit是一个IEnumerable<string>,你想要:

newsplit = newsplit.Select(x => "WW");
Run Code Online (Sandbox Code Playgroud)

您当前拥有的代码等效于以下内容:

foreach(string x in newsplit.ToList()) {
    AssignmentAction(x);
}

...

public static void AssignmentAction(string x) {
    x = "WW";
}
Run Code Online (Sandbox Code Playgroud)

x由于C#的pass-by-value语义和字符串的不变性,此方法不会修改.


Jon*_*eet 19

其他答案解释了为什么您当前的代码不起作用.这是一个可以解决它的扩展方法:

// Must be in a static non-nested class
public static void ModifyEach<T>(this IList<T> source,
                                 Func<T,T> projection)
{
    for (int i = 0; i < source.Count; i++)
    {
        source[i] = projection(source[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用:

newsplit.ModifyEach(x => "WW");
Run Code Online (Sandbox Code Playgroud)

这将适用于任何实现,IList<T>如数组和List<T>.如果你需要它与任意一起工作IEnumerable<T>那么你就会遇到问题,因为序列本身可能不是可变的.

Select()当然,使用是一种更实用的方法,但有时候改变现有的集合值得做的......

  • @Jason:几乎......但如果你调用ToList()但没有保留对该新列表的引用,则不会保留修改.特别是它不会*修改原始集合.编辑了预期用途的答案. (2认同)