当前位置: 首页 > news >正文

java源码网站/谷歌网页版入口

java源码网站,谷歌网页版入口,做暧暧视频网站安全吗,国内特效比漂亮的网站Linq延迟执行(转) LINQ中大部分查询运算符都有一个非常重要的特性:延迟执行。这意味着,他们不是在查询创建的时候执行,而是在遍历的时候执行(换句话说,当enumerator的MoveNext方法被调用时&…

 

Linq延迟执行(转)

LINQ中大部分查询运算符都有一个非常重要的特性:延迟执行。这意味着,他们不是在查询创建的时候执行,而是在遍历的时候执行(换句话说,当enumerator的MoveNext方法被调用时)。让我们考虑下面这个query:

         static void TestDeferredExecution()
{
var numbers = new List<int>();
numbers.Add(1);
IEnumerable<int> query = numbers.Select(n => n * 10); // Build query

numbers.Add(2); // Add an extra element after the query
foreach (int n in query)
Console.Write(n + "|"); // 10|20|
}

可以看出,我们在查询创建之后添加的number也包含在查询结果中了,这是因为直到foreach语句对query进行遍历时,LINQ查询才会执行,这时,数据源numbers已经包含了我们后来添加的元素2,LINQ的这种特性就是延迟执行。除了下面两种查询运算符,所有其他的运算符都是延迟执行的:

  • 返回单个元素或者标量值的查询运算符,如First、Count等。
  • 下面这些转换运算符:ToArray、ToList、ToDictionary、ToLookup。

上面两种运算符会被立即执行,因为他们的返回值类型没有提供延迟执行的机制,比如下面的查询会被立即执行。

            int matches = numbers.Where(n => (n % 2) == 0).Count();     // 1

对于LINQ来说,延迟执行时非常重要的,因为它把查询的创建与查询的执行解耦了,这让我们可以向创建SQL查询那样,分成多个步骤来创建我们的LINQ查询。

重复执行

延迟执行带来的一个影响是,当我们重复遍历查询结果时,查询会被重复执行:

        static void TestReevaluation()
{
var numbers = new List<int>() { 1, 2 };

IEnumerable<int> query = numbers.Select(n => n * 10); // Build query
foreach (int n in query) Console.Write(n + "|"); // 10|20|

numbers.Clear();
foreach (int n in query) Console.Write(n + "|"); // <nothing>
}

有时候,重复执行对我们说可不是一个优点,理由如下:

  • 当我们需要在某一个给定的点保存查询的结果时。
  • 有些查询比较耗时,比如在对一个非常大的sequence进行查询或者从远程数据库获取数据时,为了性能考量,我们并不希望一个查询会被反复执行。

这个时候,我们就可以利用之前介绍的转换运算符,比如ToArray、ToList来避开重复执行,ToArray把查询结果保存至一个Array,而ToList把结果保存至泛型List<>:

        static void TestDefeatReevaluation()
{
var numbers = new List<int>() { 1, 2 };

List<int> timesTen = numbers
.Select(n => n * 10)
.ToList(); // Executes immediately into a List<int>

numbers.Clear();
Console.Write(timesTen.Count); // Still 2
}

变量捕获

延迟执行还有一个不好的副作用。如果查询的lambda表达式引用了程序的局部变量时,查询会在执行时对变量进行捕获。这意味着,如果在查询定义之后改变了该变量的值,那么查询结果也会随之改变。

        static void TestCapturedVariable()
{
int[] numbers = { 1, 2 };

int factor = 10;
IEnumerable<int> query = numbers.Select(n => n * factor);
factor = 20;
foreach (int n in query)
Console.Write(n + "|"); // 20|40|
}

这个特性在我们通过foreach循环创建查询时会变成一个真正的陷阱。假如我们想要去掉一个字符串里的所有元音字母,我们可能会写出如下的query:

              IEnumerable<char> query = "How are you, friend.";

query = query.Where(c => c != 'a');
query = query.Where(c => c != 'e');
query = query.Where(c => c != 'i');
query = query.Where(c => c != 'o');
query = query.Where(c => c != 'u');

foreach (char c in query) Console.Write(c); //Hw r y, frnd.

尽管程序结果正确,但我们都能看出,如此写出来的程序不够优雅。所以我们会自然而然的想到使用foreach循环来重构上面这段程序:

            IEnumerable<char> query = "How are you, friend.";

foreach(char vowel in "aeiou")
query = query.Where(c => c != vowel);

foreach (char c in query) Console.Write(c); //How are yo, friend.

结果中只有字母u被过滤了,咋一看,有没有吃一惊呢!但只要仔细一想就能知道原因:因为vowel定义在循环之外,所以每个lambda表达式都捕获了同一变量。当我们的query执行时,vowel的值是什么呢?不正是被过滤的字母u嘛。要解决这个问题,我们只需把循环变量赋值给一个内部变量即可,如下面的temp变量作用域只是当前的lambda表达式

            IEnumerable<char> query = "How are you, friend.";

foreach (char vowel in "aeiou")
{
char temp = vowel;
query = query.Where(c => c != temp);
}     

        foreach (char i in "aeiou")
        {
          query=query.Where(n => n != i).ToArray();//这样也是可以的
        }


foreach (char c in query) Console.Write(c); //Hw r y, frnd.

延迟执行的实现原理

查询运算符通过返回装饰者sequence(decorator sequence)来支持延迟执行。

和传统的集合类型如array,linked list不同,一个装饰者sequence并没有自己用来存放元素的底层结构,而是包装了我们在运行时提供的另外一个sequence。此后当我们从装饰者sequence中请求数据时,它就会转而从包装的sequence中请求数据。

比如调用Where会创建一个装饰者sequence,其中保存了输入sequence的引用、lambda表达式还有其他提供的参数。下面的查询对应的装饰者sequence如图所示:

        IEnumerable<int> lessThanTen = new int[] { 5, 12, 3 }.Where(n => n < 10);

 当我们遍历lessThanTen时,实际上我们是在通过Where装饰者从Array中查找数据。

而查询运算符链接创建了一个多层的装饰者,每个查询运算符都会实例化一个装饰者来包装前一个sequence,比如下面的query和对应的多层装饰者sequence:

            IEnumerable<int> query = new int[] { 5, 12, 3 }
.Where(n => n < 10)
.OrderBy(n => n)
.Select(n => n * 10);

在我们遍历query时,我们其实是在通过一个装饰者链来查询最初的array。

需要注意的是,如果在上面的查询后面加上一个转换运算符如ToList,那么query会被立即执行,这样,单个list就会取代上面的整个对象模型。


 
Rookier http://www.cnblogs.com/smailxiaobai/archive/2012/01/06/2314653.html

 
http://www.jmfq.cn/news/5070133.html

相关文章:

  • 有域名有空间如何做网站/软文世界平台
  • seo搜索引擎优化总结报告/广州营销seo
  • 网站备案失效/查排名网站
  • 新手怎么做企业网站/长沙seo服务哪个公司好
  • 开发网站商城/网站源码交易平台
  • 义乌制作网站要多少钱/代做seo排名
  • 牛什么的网站建设/站长之家ip地址归属查询
  • 东莞大岭山森林公园/seo管理工具
  • 国外专门做旅行社的网站/电商运营入门基础知识
  • 有人用axure做网站/软文网官网
  • 中企建网站/搜索引擎优化师
  • 怎么用手机自己做网站/品牌广告
  • wordpress 单本小说站/百度信息流怎么投放
  • 保定学校网站建设/苏州网站建设公司排名
  • 海南网站开发公司/网站优化培训学校
  • 安徽省建设工程质量安全监督总站网站/上海百度推广电话客服
  • 保利拍卖公司网站/友点企业网站管理系统
  • 如何制作手机免费网站模板/微信营销和微博营销的本质区别
  • 百度收录网站标题/媒体推广
  • 中兴建设云南有限公司网站/百度怎么发布短视频
  • wordpress hsts/seo和sem的区别是什么?
  • 网站日志分析怎么做/商丘seo教程
  • 网站中下滑菜单怎么做/深圳推广公司推荐
  • 做网站签合同/成都网络营销搜索推广
  • 云网站后台操作手册/网站seo顾问
  • 邵阳做网站的公司/广州今日头条新闻
  • dw5怎样做网站/优化关键词软件
  • 做网站职校选什么专业/aso优化重要吗
  • 电子商务网站建设与维护总结/口碑营销
  • 龙岗网站建设公司哪家好/网站的seo如何优化