昨天有个同事在码一程序,处理一个list集合,检查是否有符合条件的项,但不想写繁琐的foreach检查(那样做看上去很2,不专业),于是我就顺手用linq拓展方法给写了。大致如下:

if(null != xxx.Select(p => p .... ).FirstOrDefault()) { ... };

结果发现运行的时候这个条件总是成立的,我蛋都碎了。后来我把.Select换成了.Where就好了。我仔细一看,原来.Select拓展方法遇到后面是条件判定的时候,返回的是bool类型。所以这个if语句自然就永远能走进去了。平时我用Select的时候往往后面跟着new的对象,所以一直没注意到这件事。

今天写了个小demo实验了一下:

static void Main(string[] args)
{
    var list = new List<string>() { "a", "b", "c", "aa" };

    var query1 = list.Where(p => p == "a").FirstOrDefault();
    var query2 = list.Where(p => p == "d").FirstOrDefault();
    var query3 = list.Select(p => p == "a").FirstOrDefault();
    var query4 = list.Select(p => p == "d").FirstOrDefault();

    Console.WriteLine(query1);
    Console.WriteLine(query2);
    Console.WriteLine(query3);
    Console.WriteLine(query4);
}

运行结果如下:

query2没有输出是因为FirstOrDefault()没找到符合条件的对象会返回null,如果换成First是会爆的:

实验结果证明了之前的结论。所以之前的场景,应该这样码:如果用Where拓展方法,就检查是不是null。如果用Select拓展方法,只要检查是True还是False就可以了。