像参考类型一样修改IQueryable不起作用?

Luk*_*ett 6 c# linq iqueryable

在C#中修改私有方法中的对象很常见,因为它们通常是引用类型而不是值类型,例如:

public void Main()
{
    var person = new Person();

    SetPersonsName(person);

    System.Writeln(person.Firstname + " " + person.Lastname);
}

private void SetPersonsName(Person person)
{
    person.Firstname = "Jimi";
    person.Lastname = "Hendrix";
}
Run Code Online (Sandbox Code Playgroud)

Firstname和Lastname应用于对象,并且将在我们通过引用传递对象时指向它(指向它在内存中的位置)而不是像我们为value-types所做的那样创建对象的副本.

那么如果我们有一个IQueryable并使用相同的方法将Where子句添加到对象集合中,如下所示呢?

public void Main()
{
    // Returns Jimi Hendrix and Justin Bieber
    var people = _workspace.GetDataSource<Person>();

    FilterByRockGods(people);

    foreach(var person in people)
    {
        // Will still print "Jimi Hendrix" and "Justin Bieber"
        // Should only print "Jimi Hendrix" (obviously)
        System.Writeln(person.Firstname + " " + person.Lastname);
    }
}

private void FilterByRockGods(IQueryable<Person> people)
{
    people = people.Where(x => x.IsRockGod);
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,私有方法中应用的Where子句不应用于集合

您必须执行以下操作:

public void Main()
{
    // Returns Jimi Hendrix and Justin Bieber
    var people = _workspace.GetDataSource<Person>();

    people = FilterByRockGods(people);

    foreach(var person in people)
    {
        // Prints "Jimi Hendrix"
        System.Writeln(person.Firstname + " " + person.Lastname);
    }
}

private IQueryable<Person> FilterByRockGods(IQueryable<Person> people)
{
    people = people.Where(x => x.IsRockGod);

    return people;
}
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

vc *_* 74 7

这是因为当你编写时,person.Firstname = ...你正在调用FirstName改变实例数据的属性setter.

Where相比之下,并没有改变IEnumerable它的召唤,而是产生一种新的IEnumerable.

  • 如果您使用ref参数,则可以 (2认同)