C# 在列表上使用带foreach操作的条件lambda语句

C# 在列表上使用带foreach操作的条件lambda语句,c#,lambda,C#,Lambda,为什么我不能做这样的事 如果我有一个用项目填充的列表myList,我希望能够有条件地对每个成员进行操作,如下所示: myList.ForEach(a => { if (a.Trim().Length == 0) a = "0.0"; }) 但这不会编译。我猜这与缺少返回值有关 我正在准备一个字符串列表,以便转换为双精度字符串,我希望空项显示为“0.0”,这样我就可以一次性转换整个列表 ForEach是不可变的,它不会以任何方式更改数据结构 您可以: 使用索引自己处理循环 使用.NET 3

为什么我不能做这样的事

如果我有一个用项目填充的列表myList,我希望能够有条件地对每个成员进行操作,如下所示:

myList.ForEach(a => { if (a.Trim().Length == 0) a = "0.0"; })
但这不会编译。我猜这与缺少返回值有关


我正在准备一个字符串列表,以便转换为双精度字符串,我希望空项显示为“0.0”,这样我就可以一次性转换整个列表

ForEach是不可变的,它不会以任何方式更改数据结构

您可以:

使用索引自己处理循环 使用.NET 3.5提供的.Select和.ToList生成新列表 示例1:

for (Int32 index = 0; index < myList.Count; index++)
    if (myList[index].Trim().Length == 0)
        myList[index] = "0.0";
对于.NET 3.5,不使用Linq语法,而是使用Linq代码:

myList = myList.Select(a => (a.Trim().Length == 0) ? "0.0" : a).ToList();
编辑:如果要生成新的双打列表,也可以使用Linq一次性完成:

List<Double> myDoubleList =
    (from a in myList
     select (a.Trim().Length == 0 ? "0" : a) into d
     select Double.Parse(d)).ToList();
请注意,使用0.0而不仅仅是0依赖于小数点作为句号。在我的系统上不是,所以我将其替换为0,但更合适的方法是将调用更改为Double.Parse以采用显式数字格式,如下所示:

List<Double> myDoubleList =
    (from a in myList
     select (a.Trim().Length == 0 ? "0.0" : a) into d
     select Double.Parse(d, CultureInfo.InvariantCulture)).ToList();

您可能想要的是:

public static void MutateEach(this IList<T> list, Func<T, T> mutator)
{
    int count = list.Count;
    for (int n = 0; n < count; n++)
        list[n] = mutator(list[n]);
}
只需将MutateEach方法放在自己的公共静态类中,并确保有一个using指令可以找到它

定义这样的东西是否值得取决于你使用它的频率。请注意,它必须是IList上的一个扩展,而不是IEnumerable,因此我们可以执行更新,这使得它的应用范围不那么广泛。

@daniel earwicker的MutateEach扩展解决方案是一个很好的解决方案

不过,为了返回新列表,您可以选择使用List.ConvertAllConverterFunc,它自.NET 2.0以来就一直存在

这不是林克,也不是兰姆达


嗯,好的,有没有任何扩展方法可以让你对列表中的每一项进行操作?我不知道,而且我怀疑,大多数Linq方法都是以函数式的方式构建的,不允许以任何方式更改输入。你们真是太棒了。每次我在这个网站上提问,我都会学到一些东西。我强烈建议你访问www.lambdaexpression.net
public static void MutateEach(this IList<T> list, Func<T, T> mutator)
{
    int count = list.Count;
    for (int n = 0; n < count; n++)
        list[n] = mutator(list[n]);
}
myList.MutateEach(a => (a.Trim().Length == 0) ? "0.0" : a);
List<String> nodeStringList = new List<String>(new String[] { "", "0.5 ", " 1.1"}); 

nodeStringList = nodeStringList.ConvertAll<String>((c) => (c.Value.Trim().Length != 0) ? c.Value.Trim() : "0.0");