zoukankan      html  css  js  c++  java
  • LINQ中的"延迟查询"特性

            很多标准查询操作符的设计原型都是返回一个IEnumerable<T>类型的序列, 这些标准查询操作实际上不会在代码执行到那一行的时候就返回一个序列, 事实上返回的是一个对象. 当在枚举(比如foreach)这个对象的时候会从IEnumerable<T>序列中生成一个元素, 这个时候才会真正执行查询操作. 这就是所谓的"延迟查询".

    小例子证明"延迟查询"的存在性

    int[] intArray = new int[] { 0, 1, 2, 3 };
    IEnumerable<int> items = intArray.Select(i => i); //返回i
    //输出结果
    foreach (int item in items)
        Console.WriteLine(item);
    //更改一下intArray中的某个元素, 再进行"输出结果"
    intArray[0] = 4;
    Console.WriteLine("改变intArray第一个元素值之后的输出结果:");
    //再次输出结果
    foreach (int item in items)
        Console.WriteLine(item);

            两次输出结果分别为:0, 1, 2, 3 和 4, 1, 2, 3. 由此可见只有在枚举items的时候才会真正的执行查询操作. 如果没有延迟查询, 两次输出的结果应该是相同的.

    避免"延迟查询"的方法

            可以使用一个不返回IEnumerable<T>数据类型的转换操作符, 如ToArray, ToList, ToDictionary或ToLookup, 这样查询操作就不会被延迟了. 同样是上面例子的, 通过ToList操作符返回一个List<int>型序列, 就不会产生"延迟查询"的现象:

    int[] intArray = new int[] { 0, 1, 2, 3 };
    List<int> items = intArray.Select(i => i).ToList(); //加了ToList操作符
    //输出结果
    foreach (int item in items)
        Console.WriteLine(item);
    //更改一下intArray中的某个元素, 再进行"输出结果"
    intArray[0] = 4;
    Console.WriteLine("改变intArray第一个元素值之后的输出结果:");
    //再次输出结果
    foreach (int item in items)
        Console.WriteLine(item);

            这样两次输出的结果就都为0, 1, 2, 3了.

    "延迟查询"可能导致的错误

            因为有了延迟, 被枚举的时候才会真正的去执行一个查询, 因此如果程序编译通过了但绝对不意味着这个查询就是没事儿的. 比如查询一个字符串数组里面, 每个元素的第3个字符是什么的时候, 如果某个字符串长度<3, 那么在运行的时候就会报错, 而程序在编译的时候是没有问题的.

    作者:Create Chen
    出处:http://technology.cnblogs.com
    说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
    知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

  • 相关阅读:
    CSS3阴影 box-shadow的使用和技巧总结
    事件
    表单操作
    DOM
    BOM
    js总结1
    css3
    css图片文字相关属性
    CSS盒子模型及布局
    写博客的几个注意事项
  • 原文地址:https://www.cnblogs.com/technology/p/1962114.html
Copyright © 2011-2022 走看看