LINQ查询通常是延迟查询的,不会在调用查询表达式的时候执行。
比如下面的代码
static void Main(string[] args)
{
//准备一个数组
string[] siteNames = { "www.bamn.cn", "www.bamn.com", "www.bamn.net" };
//下面的这句代码并不会执行 where select都不会马上执行
var sites =
from s in siteNames
where s.StartsWith("www")
select s;
//只有用到这个查询结果sites的时候才会执行查询
foreach (var item in sites)
{
Console.WriteLine(item);
}
Console.ReadKey();
}Code language: JavaScript (javascript)
事实上,只有结果序列被枚举的时候才会真正执行。这样,在编写linq表达式的时候,执行也不会出错。而是在查询序列最终被枚举的时候才会产生一个异常。而这个时候枚举的时候可能距离查询表达式很远,很多人容易找不到这个查询表达式才是真正出错的原因。
比如下面的代码
static void Main(string[] args)
{
//有一个null的元素
string[] siteNames = { "www.bamn.cn", null, "www.bamn.net" };
//执行length的时候其实会出错 但是下面语句不出错
var sites = siteNames.Where(s => s.Length > 4);
//下面代码进行了枚举 所以会抛出异常
foreach (var item in sites)
{
Console.WriteLine(item);
}
Console.ReadKey();
}Code language: JavaScript (javascript)
利用延迟查询,我们可以把IEnumerable变量保存起来,然后以后每次使用,都只需要枚举这个变量就可以了。并且每次枚举的时候都是获取最新的数据。我们可以重复利用多次这个变量,只需要构建一次查询表达式就可以。
static void Main(string[] args)
{
//准备一个数组
var siteNames = new List<string> { "www.bamn.cn", "www.bamn.com", "www.bamn.net" };
//下面的这句代码并不会执行 where select都不会马上执行
var sites =
from s in siteNames
where s.StartsWith("www")
select s;
//只有用到这个查询结果sites的时候才会执行查询
foreach (var item in sites)
{
Console.WriteLine(item);
}
Console.WriteLine("--------------");
//改成集合的数据 但是IEnumerable还是原来的
siteNames.Add("www.google.com");
foreach (var item in sites)
{
Console.WriteLine(item);
}
Console.ReadKey();
}Code language: PHP (php)
Previous: Cast和ofType的使用转换成IEnumerable类型