我有以下代码:
newsplit.ToList().ForEach(x => x = "WW");
我希望列表中的所有元素现在都是“WW”,但它们仍然是原始值。怎么会?我该怎么办?
答案 0 :(得分:35)
假设newsplit
是IEnumerable<string>
,您需要:
newsplit = newsplit.Select(x => "WW");
您目前拥有的代码等同于以下内容:
foreach(string x in newsplit.ToList()) {
AssignmentAction(x);
}
...
public static void AssignmentAction(string x) {
x = "WW";
}
由于C#的pass-by-value语义和字符串的不变性,此方法不会修改x
。
答案 1 :(得分:18)
其他答案解释了为什么您当前的代码不起作用。这是一个可以修复它的扩展方法:
// 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]);
}
}
然后像这样使用:
newsplit.ModifyEach(x => "WW");
这适用于IList<T>
的任何实现,例如数组和List<T>
。如果你需要它来处理任意IEnumerable<T>
,那么你就会遇到问题,因为序列本身可能不是可变的。
当然,使用Select()
是一种更具功能性的方法,但有时会改变现有的 值得...
答案 2 :(得分:2)
ForEach将允许您操作IEnumerable的元素,但不能更改元素的引用。
即,这会将IEnumerable中每个元素的Foo
属性设置为字符串"WW"
:
newsplit.ToList().ForEach(x => x.Foo = "WW");
但是,您将无法修改IEnumerable本身内的值。
答案 3 :(得分:1)
您可以这样写:
newsplit = newsplit.Select(x => "WW").ToList();
答案 4 :(得分:0)
这是因为LINQ表达式正在创建Anonymous Types,这些是只读的。他们无法分配。此外,在每个循环的标准中,您无法分配给正在枚举的集合。尝试:
foreach (var item in newsplit)
{
item = "this won't work";
}