更改List .ForEach ForEach方法中的元素值
我有以下代码:
newsplit.ToList().ForEach(x => x = "WW");
我希望列表中的所有元素现在都是“WW”,但它们仍然是原始值。 怎么会? 我该怎么办?
假设newsplit
是一个IEnumerable
,你想要:
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
。
其他答案解释了为什么您当前的代码不起作用。 这是一个可以修复它的扩展方法:
// Must be in a static non-nested class public static void ModifyEach(this IList source, Func projection) { for (int i = 0; i < source.Count; i++) { source[i] = projection(source[i]); } }
然后像这样使用:
newsplit.ModifyEach(x => "WW");
这适用于IList
任何实现,例如数组和List
。 如果你需要它来处理任意IEnumerable
那么你就会遇到问题,因为序列本身可能不是可变的。
当然,使用Select()
是一种更实用的方法,但有时候改变现有的集合是值得做的......
ForEach将允许您操作IEnumerable的元素,但不能更改元素的引用。
即,这会将IEnumerable中每个元素的Foo
属性设置为字符串"WW"
:
newsplit.ToList().ForEach(x => x.Foo = "WW");
但是,您将无法修改IEnumerable本身内的值。
这是因为LINQ表达式创建了匿名类型 ,这些是只读的。 他们无法分配。 此外,在每个循环的标准中,您无法分配给正在枚举的集合。 尝试:
foreach (var item in newsplit) { item = "this won't work"; }