代码之家  ›  专栏  ›  技术社区  ›  Andrew Rollings

LINQ查询-需要解释为什么这些示例不同

  •  8
  • Andrew Rollings  · 技术社区  · 17 年前

    书中的解释有点简短,所以我想知道是否有人能为我一步一步地把它分解,这样它才有意义。。。

        IEnumerable<char> query2 = "Not what you might expect";
        foreach (char vowel in "aeiou")
        {
            var t = vowel;
            query2 = query2.Where(c => c != t);
            // iterate through query and output (snipped for brevity)
        }
    

    输出如下:

        Not wht you might expect
        Not wht you might xpct
        Not wht you mght xpct
        Nt wht yu mght xpct
        Nt wht y mght xpct
    

        IEnumerable<char> query2 = "Not what you might expect";
        foreach (char vowel in "aeiou")
        {
            query2 = query2.Where(c => c != vowel);
            // iterate through query and output (snipped for brevity)
        }
    
        Not wht you might expect
        Not what you might xpct
        Not what you mght expect
        Nt what yu might expect
        Not what yo might expect
    

    这不。。。

    2 回复  |  直到 17 年前
        1
  •  10
  •   Lasse V. Karlsen    17 年前

    第一个例子的情况是元音的值被捕获到一个局部(for循环的范围)变量中。

    但是,在第二个类中,它不捕获当前值,只捕获要使用的变量,因此,由于此变量发生变化,每次执行循环时,您都会在上一个Where子句的基础上构建一个新的Where子句,但由于您更改了变量,您也会修改前面的所有子句。

    因此,在第一个示例中,您得到了这种类型的查询:

    IEnumerable<char> query2 = "Not what you might expect";
    Char t1 = 'a'; query2 = query2.Where(c => c != t1);
    Char t2 = 'e'; query2 = query2.Where(c => c != t2);
    Char t3 = 'i'; query2 = query2.Where(c => c != t3);
    Char t4 = 'o'; query2 = query2.Where(c => c != t4);
    Char t5 = 'u'; query2 = query2.Where(c => c != t5);
    

    IEnumerable<char> query2 = "Not what you might expect";
    Char vowel = 'a'; query2 = query2.Where(c => c != vowel);
    vowel = 'e'; query2 = query2.Where(c => c != vowel);
    vowel = 'i'; query2 = query2.Where(c => c != vowel);
    vowel = 'o'; query2 = query2.Where(c => c != vowel);
    vowel = 'u'; query2 = query2.Where(c => c != vowel);
    

    在执行第二个示例时 vowel

    在使用匿名方法/lambda时,捕获变量是我们都会遇到的问题之一,您可以在此处阅读更多相关内容: C# In Depth: The Beauty of Closures .

    ,你会发现这种行为的一些例子。

        2
  •  1
  •   Andrew Rollings    17 年前

    事实上,重读它,它是有意义的。 使用temp变量意味着在查询中捕获temp本身。。。我们对循环进行了五次评估,因此每个查询版本都有五个实例化的temp变量引用。

    在没有temp变量的情况下,只有循环变量的引用。

    在第一种情况下,一旦对循环进行了完整的计算,查询就使用了对temp变量的五个引用,从而分别剥离出a、e、i、o和u。

    在第二种情况下,它也在做同样的事情。。。只有所有五个引用都指向同一个变量,该变量显然只包含一个值。

    那么,现在这对其他人有意义吗?