1

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

3 回答 3

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

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

于 2012-09-06T22:25:29.330 回答
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)
    {

    }

这是经过测试的

于 2012-09-06T22:35:38.207 回答
0
people.Where(p => string.IsNullOrWhiteSpace(p.Name)).ToList().ForEach(cc=>cc.Name="Foo");
于 2015-01-10T06:29:50.213 回答