zoukankan      html  css  js  c++  java
  • C#中LINQ数据模型解析

    假如有一个集合,里面有数字1-10,现在想实现从这10个数字中取出偶数数字,然后将得到的偶数乘以10,最后输出前三个。代码如下

    代码非常的简单,最后会得到20、40、60这三个数字,但结果并不是我们今天最关注的事。今天我们想讨论下numbers中的数字是如何Where、Select、Take这三个方法中流转的。也许你会认为,是这样流转的。如下:

    一般我们会向上图这样理解:Where中生成并返回符合条件的新数组,然后将这个数组交个Select处理,Select中生成并返回新数组,再交由Take处理,Take取出前三个数并返回新数组。

    其实并不是这样,我们知道Linq是由一系列基于IEnumerable的扩展方法组成,返回值也都是IEnumerable,而IEnumerable只是一个迭代器对象,每次读取IEnumerable对象时,其实只是遍历里面的一个元素。上面方法的真正流程应该是流式的类似管道的操作,即读一个数字处理一个,边读边处理。如下:

    这样数据逐个在方法中处理就构成了数据管道,这里还有一个地方需要注意,很多Linq方法是延迟操作,比如我们例子中的Where、Select、Take这些,但ToList、Count、Sum会立即执行。延迟操作就是只是定义如何操作数据,但不会真正执行,等到数据真正使用的时候才会执行。我们来验证下,比如我在Select中故意抛一个异常,试下。代码如下:

    我们再次执行一下,异常不会报出。代码如下:

    其实代码中的filter变量可以理解成一堆算法的包装器,只是封装了一系列对数据的操作,但只有元素被使用时才会执行。我们在代码后加一段遍历filter并输出的代码,这时元素被使用到了,就会报错了。代码如下:

    好了,我们要讲的内容就讲完了,内容非常浅,相信很多人都是知道的,大家可以去看下Linq的源码,相信收获会更多。管道的思想其实应用非常多,比如链式编程、建造者模式,在dotcore中用的就更多了。

    文章内容转载自小小架构师

  • 相关阅读:
    Java 得到指定时间加半个小时之后得时间
    MySQL查询point类型类型的坐标,返回经度纬度
    MySQL通过实体经纬度字段插入数据库point类型的经纬度字段
    MySQL通过POIN数据类型查询指定范围内数据
    Java 根据两个经纬度,得到两点距离
    mysql通过经纬度查询400公里范围内的小区
    位运算
    Hibernate多对多删除问题的解决
    mysql 中 时间和日期函数
    Struts2数据传输的背后机制:ValueStack(值栈)
  • 原文地址:https://www.cnblogs.com/zmdblogs/p/13895442.html
Copyright © 2011-2022 走看看