LINQ表达式有多种方法

时间:2016-12-29 19:36:28

标签: c# linq

我编写了以下代码,但我无法理解为什么它只返回两个元素而不是全部。看起来“Where”方法仅适用于最后添加的方法。

class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
}

class Program
{
    public static bool IsAdult(Person person)
    {
        return person.Age > 18;
    }

    public static bool MethodTrue(Person person)
    {
        return true;
    }

    static void Main()
    {
        var list = new List<Person>
        {
            new Person() { Age = 20, Name = "Artur" },
            new Person() { Age = 30, Name = "Adam" },
            new Person() { Age = 10, Name = "Wieslaw" },
            new Person() { Age = 15, Name = "Michal" }
        };


        Func<Person, bool> predicate = null;
        predicate += MethodTrue;
        predicate += IsAdult;

        var res = list.Where(predicate);
    }
}

4 个答案:

答案 0 :(得分:4)

如果以这种方式连接代理,所有代理都将被执行,但只能从 last 获得结果。 请使用代表了解此情况: https://msdn.microsoft.com/en-us/library/ms173172.aspx

如果委托具有返回值和/或输出参数,则返回返回值和调用的 last 方法的参数。

反向顺序将为您提供所有结果:

Func<Person, bool> predicate = null;
predicate += IsAdult;
predicate += MethodTrue;

但是我没有看到以这种方式做linq的任何意义。你可以写

Func<Person, bool> predicate = x=> IsAdult(x) || MethodTrue(x);

&&,这取决于您实际想要实现的目标。

答案 1 :(得分:2)

你链接两个谓词的方式,它只关心最后一个(这里是第二个)。

即使不是这种情况,MethodTrue()总是返回true,只有两个人通过了IsAdult的标准,这就是为什么它只返回两个项目。顺便说一下,你真的不需要predicate变量。你可以这样写:

var res = list.Where(p => MethodTrue(p) && (IsAdult(p)));

答案 2 :(得分:0)

您的结果集正在根据您的谓词进行过滤。您的谓词定义为:IsAdult,它将执行年龄比较 AND MethodTrue,它将始终返回true。因此,如果人员年龄未通过age > 18检查,则您的where语句将失败,列表中的该项目将失败。

所以你的where子句只返回2个值,因为根据你IsAdult函数的逻辑,只有2个人是成年人。

基于谓词的结果:

var list = new List<Person>
    {
        new Person() { Age = 20, Name = "Artur" },
        new Person() { Age = 30, Name = "Adam" }
    };

如果您要查看or (||)语句,可以按照以下方式编写谓词,以返回Maksim Simkin提到的所有值。

 Func<Person, bool> predicate = x => IsAdult(x) || MethodTrue(x); 

答案 3 :(得分:-2)

当您在谓词中提供两个函数时,它们将使用按位AND (&&)进行求值,这意味着只包含两个函数都返回的对象。由于您使用Person过滤掉了IsAdult()个对象18及更年轻的对象,因此只能从该函数返回两个记录。这意味着按位操作永远不会返回超过这两个记录。