在定义linq查询表达式时,查询是不会执行,查询会在迭代数据项时运行。它使用yield return 语句返回谓词为true的元素。

var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };
var namesWithJ = from n in names
                 where n.StartsWith("J")
                 orderby n
                 select n;
Console.WriteLine("First iteration");
foreach (string name in namesWithJ)
{
    Console.WriteLine(name);
}
Console.WriteLine();

names.Add("John");
names.Add("Jim");
names.Add("Jack");
names.Add("Denny");

Console.WriteLine("Second iteration");
foreach (string name in namesWithJ)
{
    Console.WriteLine(name);
}

运行结果为

First iteration
Juan

Second iteration
Jack
Jim
John
Juan

从执行结果可以看出,当在定义namesWithJ时并不会执行,而是在执行每个foreach语句时进行,所以后面增加的“John”、“Jim”、“Jack”和“Denny”在第二次迭代时也会参与进来。

ToArray()、ToList()等方法可以改变这个操作,把namesWithJ的定义语句修改为

var namesWithJ = (from n in names
                  where n.StartsWith("J")
                  orderby n
                  select n).ToList();

运行结果为

First iteration
Juan

Second iteration
Juan

在日常工作中,我们常会使用 datas.Where(x=>x.XX == XXX).FirstOrDefault() 和 datas.FirstOrDefault(x=>x.XX == XXX),其实这两种写法性能是等效的,如果真的要在性能上分个高低,请见接下来的文章

应避免错误写法是 datas.Where(x=>x.XX == XXX).ToList()[0]。

04-19 10:45