【问题标题】:Is there any way to do this, assign a value within a List<T>.ForEach() statement?有没有办法做到这一点,在 List<T>.ForEach() 语句中分配一个值?
【发布时间】:2015-06-01 18:57:35
【问题描述】:

我有这个:

var lineArray = line.Split(';');

lineArray.ToList().ForEach(x =>
{
    if (x == "(null)")
        x = "NULL";
    else
        x = string.Format("'{0}'", x);
});

这运行良好,但似乎没有改变lineArray 中的元素。我想将ForEach 的结果分配给var,但它返回无效。

有什么想法吗?

编辑:我认为这是因为 ToList() 返回值没有分配到任何地方......

【问题讨论】:

  • 不要像那样使用ForEach - 使用for 循环。
  • @Steve 我不会说rare。在很多情况下,每一种都有其独特的优点。
  • 无论你怎么做,仅仅重新分配给x 并不会改变源序列。您需要将新的x 写回列表或数组。当然,下面的答案向您展示了实现目标的各种技巧。

标签: c# .net-3.5


【解决方案1】:
var lineArray = line.Split(';')
                    .Select(x=>x == "(null)"
                               ? "NULL"
                               : string.Format("'{0}'", x))
                    .ToArray();

您正在尝试将 List&lt;T&gt;.ForEach(Action&lt;T&gt; action) 与 lambda 表达式一起使用(此处的 T 是字符串)

如果将 lambda 表达式替换为命名方法,结果只会修改方法参数,但更改不会反映在调用方,因为 x 不是 ref 参数

private void Replace(string x)
{
    if (x == "(null)")
        x = "NULL";
    else
        x = string.Format("'{0}'", x);
}

var list = lineArray.ToList();
list.ForEach(Replace);
// check list here and make sure that there are no changes

如果 T 是引用类型并且操作修改了某些属性但不修改引用本身,则 ForEach 可以工作

【讨论】:

  • 第二个例子应该有效吗?因为它不能工作。你想在那里展示什么?
  • @poke,第二个例子是没有 lambda 的问题代码的翻译。 lambda 增加了一些复杂性,并使用命名方法(当然不会修改列表)的示例显示了它的实际工作原理
  • 哦,我明白了。从你写它的方式来看,这并不是很清楚。
【解决方案2】:

不要像那样使用ForEach - 使用for 循环。

for (int i = 0; i < lineArray.Length; i++)
{
    if (lineArray[i] == "(null)")
        lineArray[i] = "NULL";
    else
        lineArray[i] = string.Format("'{0}'", lineArray[i]);
}

【讨论】:

    【解决方案3】:

    您可以从原来的列表中构建一个新列表:

    var newList = lineArray.Select(x => x == "(null)" ? "NULL" : string.Format("'{0}'", x));
    

    【讨论】:

    • 以内存为代价,这可能很重要,也可能无关紧要。
    【解决方案4】:

    我认为这个小改动会奏效

     var lineArray = line.Split(';').ToList();
    
            lineArray.ForEach(x =>
            {
                if (x == "(null)")
                    x = "NULL";
                else
                    x = string.Format("'{0}'", x);
            });
    

    下面是一个工作示例

    string line = "a;b;null;c;";
    
    var lineArray = line.Split(';').ToList();
    
        lineArray.ForEach(x =>
        {
            if (x == "(null)")
                x = "NULL";
            else
                x = string.Format("'{0}'", x);
        });
    

    结果:

    如果您只需要从列表中删除(空)值,则不需要循环 只需使用 removeAll

        lineArray.RemoveAll(a=>a.Equals("(null)"));
    

    下面的工作示例

    【讨论】:

    • 您的“工作示例”演示了您的解决方案不起作用。 提示:查看空值。重新分配给 x 不会影响源序列中的元素。
    • 所以你想删除元素?不只是改变价值?
    • 您的解决方案不会更改源序列中的值。您正在覆盖输入参数变量 x,它不会更改源。
    猜你喜欢
    • 1970-01-01
    • 2011-10-04
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多