C#中List.ForEach修改字符串列表元素不生效问题
问题根因
你遇到的问题本质是两个C#基础特性共同导致的:
- string是不可变引用类型,所有对字符串的"修改"本质都是生成新的字符串对象,不会改动原字符串本身
List<T>.ForEach方法传入的lambda里,参数file是值传递的局部变量,它只是复制了列表对应位置元素的引用,你给这个局部变量重新赋值(file = xxx),只会改变局部变量的指向,完全不会修改列表中存储的原始元素引用。
简单说:你在lambda里改的只是临时拷贝的副本,原列表里的值从头到尾都没被碰过,所以最后拼接出来的还是原字符串。
修正实现
不要尝试在ForEach的lambda里通过给参数赋值修改集合元素,两种常用的正确写法:
写法1:通过索引直接修改原列表元素
用普通for循环通过索引访问列表位置,直接给对应位置赋值新值:
using System.Globalization; public static string Capitalize(string fileName) { TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo; List<string> splittedFileName = fileName.Split('_').ToList(); for (int i = 0; i < splittedFileName.Count; i++) { // 直接修改列表索引位置存储的引用,才是真正更新列表元素 splittedFileName[i] = textInfo.ToTitleCase(splittedFileName[i]); } return string.Join("_", splittedFileName); }
写法2:用LINQ直接投影生成新序列(更简洁)
不需要先转List再做原地修改,分割字符串后直接用Select投影处理每个分段,再拼接即可,代码更简洁:
using System.Globalization; using System.Linq; public static string Capitalize(string fileName) { TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo; return string.Join("_", fileName.Split('_').Select(part => textInfo.ToTitleCase(part)) ); }
两种写法传入测试用例test_all_first_letters_uppercase时,都会返回预期结果:
Test_All_First_Letters_Uppercase
内容的提问来源于stack exchange,提问作者dns_nx
相关产品推荐
相关产品推荐

