如何从Linq Extension方法中使用的lambda表达式主体修改对象?

时间:2016-08-07 05:35:52

标签: c# linq lambda

当使用带有Select扩展方法的lambda表达式时,我想要副作用,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SyntaxExperiment {

    public class Program {
        static void Main() {
            var list = new List<int>();
            var results = new[] { 1, 2, 3 }
                .Select(
                    i => {
                        list.Add(i);
                        return i;
                    }   
                );
            Console.WriteLine(list.Count);
        }
    }
}

上面的代码输出:

0

这怎么可能?

3 个答案:

答案 0 :(得分:3)

LINQ代码实际上并没有执行,因为它只是一个没有理由执行的IEnumerable<int>。您可以强制它执行如下:

var results = new[] { 1, 2, 3 }
    .Select(i => {
        list.Add(i);
        return i;
    })
    .ToList();

换句话说,枚举通过它枚举之前不做任何事情,而ToList则强制将数据强制转换为集合,导致枚举。

答案 1 :(得分:1)

LINQ建立在函数式编程原理的基础之上,因此虽然它可以完成但并非真正用于改变数据或通过副作用来处理事务。

你想做什么(假设真实的代码比你的例子更复杂!)是选择必要的数据然后将IEnumerable转换成List。

var results = new[] { 1, 2, 3 }.Select(i => i).ToList();

答案 2 :(得分:1)

您也可以使用下面的Foreach

static void Main()
{
    List<int> list = new List<int>();
    var results = new[] { 1, 2, 3 };
    results.ToList().ForEach(i => list.Add(i));
    Console.WriteLine(list.Count);
}