zoukankan      html  css  js  c++  java
  • LINQ之路 6:延迟执行(Deferred Execution) 笔记

    这里刚看的时候不理解。

    这个特性在我们通过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 c in query) Console.Write(c); //Hw r y, frnd.
    复制代码

     

    仔细想想也没什么问题。因为LINQ查询的时候,生成的方法,每个方法都不是直接执行,而是都指向的是vowel的引用,而VOWEL引用在遍历结束后的值为u,实际上是执行了多次的query = query.Where(c => c != vowel);              

    而写成内部临时变量,则每个query指向的是不同的temp。

  • 相关阅读:
    sql_mode=only_full_group_by引起group by查询报错问题
    在Eclipse下使用ant,build项目报jpeg does not exist
    JAVAEE面试之Hibernate缓存
    页面加载中效果实现
    鼠标滑过显示图片
    VSFTP配置参数详解
    FTP上传核心方法
    java对File的特殊操作
    在mybatis下使用日期比对出错
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/3207568.html
Copyright © 2011-2022 走看看