我试图使用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();
答案 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");