使用linq设置值时的奇怪结果

时间:2012-09-06 22:21:09

标签: c# linq

我试图使用LINQ在我的列表中设置一些值,但不知何故,以下代码将没有设置值。

class Person
{
    public string name;
    public Person(string name)
    {
        this.name = name;
    }
}

List<Person> people = new List<Person>() { new Person("a"), new Person("b") };
people.Select(x => { x.name = "c"; return x; });
foreach (Person person in people)
{
    Console.WriteLine(person.name);
}

但是,如果在调用select方法后添加ToList(),则将设置值:

List<Person> people = new List<Person>() { new Person("a"), new Person("b") };
people.Select(x => { x.name = "c"; return x; }).ToList();

更奇怪的是,如果我在一个单独的行上调用ToList(),它将无法正常工作:

List<Person> people = new List<Person>() { new Person("a"), new Person("b") };
people.Select(x => { x.name = "c"; return x; });
people.ToList();

3 个答案:

答案 0 :(得分:4)

通常,不生成产生副作用的LINQ查询总是一个好主意。您的整个目标是在Select()声明中产生副作用。

ToList()导致此效果的原因是LINQ查询在枚举结果之前不会执行。 ToList()导致查询结果被完全枚举(以便构建列表)。如果你要写:

foreach (Person person in people.Select(x => { x.name = "c"; return x; }))
{

你会看到效果发生,因为foreach遍历结果。

话虽如此,使用LINQ写入值的“正确”方法是过滤,然后稍后更改:

var peopleToEdit = people.Where(p => string.IsNullOrWhiteSpace(p.Name));
foreach(var person in peopleToEdit)
    person.Name = "Foo"; // Assign like so

基本上,查询应该是无副作用的,然后使用正常的控制流来实际编辑值。

答案 1 :(得分:0)

使用.Where子句。

    List<Person> people = new List<Person>() { new Person("C"), new Person("b") };
    var something = people.Where(x => x.name == "C");
    foreach(var x in something)
    {

    }

这是经过测试的

答案 2 :(得分:0)

people.Where(p => string.IsNullOrWhiteSpace(p.Name)).ToList().ForEach(cc=>cc.Name="Foo");