1.解剖Linq to object
LINQ想必大家都不陌生了,它的出现使得我们的代码变得更短、更优雅了。至于LINQ是什么,Linq to object这类的扩展方法到底做了些什么。我们使用的EF是如何实现的(如何解析Expression)。我都将一一为大家分享下我的理解。如果有说得不对的地方,也请大家指出。下面进入正题
大家先将代码左上角的using System.Linq去掉
当我们想对一个集合的数据进行筛选的时候,我们以前会这样做
static void Main( string [] args) { List< int > list = new List< int >() { 2,3,6,4,7,8 }; List< int > result = new List< int >(); foreach ( var item in list) { if (item < 4) { result.Add(item); } } } |
但我们仔细想想,我们要筛选数据时,就一定要遍历它,所以循环这部份是必须的。还有什么是必须的呢?筛选条件!筛选数据时筛选的条件是不同的,但它们有个共同的特点,那就是条件的结果不是true就是false。既然有这么多的共同点,我们能不能把它抽象出来写成一个通用的扩展方法供我们调用呢?聪明的你估计已经想到这个方法大概要怎样构造了。这个方法的参数有2个,一个是我们要进行数据筛选的集合,另一个是我们的筛选条件。方法体里面要做的就是去遍历这个集合,当满足筛选条件时,我们就把这个元素存到结果集合中,最后返回结果集合。想必完成后的代码是这样的
public static List< int > Where(List< int > list, Func< int , bool > func) { List< int > result = new List< int >(); foreach ( int item in list) { bool istrue = func(item); //执行我们的筛选函数 if (istrue) //如果满足筛选条件,就添加进result集合中 { result.Add(item); } } return result; } |
这时我们就可以这样进行数据筛选了,是不是清爽简洁了很多?
1
2
3
4
5
6
7
8
9
|
static void Main( string [] args) { List< int > list = new List< int >() { 2,3,6,4,7,8 }; var result = Where(list, x => x < 4); var result2 = Where(list, x => x / 2 == 0); } |
但问题来了。我们的方法只支持List<int>啊,如果换成int[]就不行了。怎么解决呢?仔细想想我们只需要遍历它就可以了,不需要对它操作啊,想到遍历想到什么?foreach!想到foreach想到什么?IEnumerable!不多说。马上搞起。修改后应该变成这样
static void Main( string [] args) { List< int > list = new List< int >() { 2,3,6,4,7,8 }; int [] array = list.ToArray(); var result = Where(array, x => x < 4); var result2 = Where(list, x => x / 2 == 0); } public static IEnumerable< int > Where(IEnumerable< int > list, Func< int , bool > func) { foreach ( int item in list) { bool istrue = func(item); if (istrue) { yield return item; } } } |
看似已经完成了,但我们往细的想想,我们的方法只支持int类型,我们想把它变成通用的,任何类型都支持。这时我们想到什么?没错,泛型。。
还有,我们平时都是list.Where(条件)来调用的。相信很多同学都知道吧,这种叫做扩展方法。我们如何改呢?下面让我们来一口把这个Where方法完成吧!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
class Program { static void Main( string [] args) { List< int > list = new List< int >() { 2,3,6,4,7,8 }; int [] array = list.ToArray(); array.Where(x => x > 0); list.Where(x => x / 2 == 0); } } public static class MyLinq { public static IEnumerable<T> Where<T>( this IEnumerable<T> list, Func<T, bool > func) { foreach (T item in list) { bool istrue = func(item); if (istrue) { yield return item; } } } } |
小贴士:扩展方法就是静态类中的静态方法,参数有this xxx。这个静态类不能是内部类
想必大家现在对LINQ有了一定的认识了吧?看完后是不是觉得LINQ其实就那么回事呢?看完后也要做下练习来巩固下吧。下面请大家自行完成一个Select扩展方法。答案在文章末尾。
这也是我第一篇博文,写的时候手都在抖,怕表达不清或说错了什么误导了大家。很早就开始想写博文了,但都太忙了。现在总算有个开始了
练习题答案
1
2
3
4
5
6
7
8
|
public static IEnumerable<TResult> Select<TInput, TResult>( this IEnumerable<TInput> list, Func<TInput, TResult> func) { foreach (TInput item in list) { TResult result = func(item); yield return result; } } |
1.解剖Linq to object的更多相关文章
- 解析LINQ To Object
1.解剖Linq to object 此文转载自http://www.cnblogs.com/irenebbkiss/p/4155480.html LINQ想必大家都不陌生了,它 的出现使得我们的 ...
- .NET面试题系列[13] - LINQ to Object
.NET面试题系列目录 名言警句 "C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard LINQ是Language Integrated Que ...
- LINQ系列:Linq to Object投影操作符
投影是指在将序列中的元素转换为一个自定义形式的操作.投影操作符Select和SelectMany用于选择出赋予了适当功能的值.SelectMany操作符可以处理多个集合. LINQ表达式语法: 1. ...
- LINQ系列:Linq to Object生成操作符
生成操作符从现有序列值中创建新的序列. 1. Empty Empty操作符返回一个指定类型的空集. 1>. 原型定义 public static IEnumerable<TResult& ...
- LINQ系列:Linq to Object转换操作符
转换是指将输入对象的类型转变为序列的动作. 1. AsEnumerable AsEnumerable操作符将查询的输入以IEnumberable(T)类型返回. 2. Cast Cast操作符将IEn ...
- LINQ系列:Linq to Object量词操作符
量词操作符返回一个Boolean值,指示序列中是否存在部分或全部元素符号指定条件.LINQ中量词操作符包括:All.Any和Contains. 1. All All操作符判定在集合中是否所有的值都满足 ...
- LinQ To Object 基本用法
http://www.cnblogs.com/terryzh/archive/2012/11/10/2763538.html LinQ To Object 基本用法 inq的基本语法:var resu ...
- SQO (标准查询运算符)方法 & Linq To Object
#region SQO (标准查询运算符) 方法 #region Where() Find() FindAll() FirstOrDefault()等方法 static void c01where() ...
- Linq to EF 与Linq to Object 使用心得
大家都知道Linq既可以用来查询数据库对象(我这里指的是Entity FrameWork里的Model对象),也可以用来查询内存中的IEnumerable对象. 两者单独查询时都不会出现什么问题,不过 ...
随机推荐
- hdu 3032 Nim or not Nim?(搜索打SG表)
题意: 有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) , 也可以选择将这堆石子分成任意的两堆.alice与bob轮流取,取走最后一个石子的人胜利. 思路: 因为数的范 ...
- WPF之RichTextBox丢失光标仍然选中文本
描述:开发中完成了一个类似于Word的悬浮工具栏功能,选中文本之后可以自动弹出一个工具栏.可以修改字体.字体大小等功能,问题来了,我发现当去进行操作的时候原本选中的RichTextBox的内容的颜色会 ...
- iOS 限制UITextField输入字符
开篇 之前做过一个即时通信的项目,需要限制输入框文本的字符个数,当时从网络上搜寻了几个方法,解决了需求,但是网络上的解决办法不是很全面:今天又遇到一个限制搜索框UISearchBar输入字符个数的问题 ...
- Hibernate常见错误整理
Hibernate常见错误合集 1.错误:object references an unsaved transient instance - save the transient instance ...
- Java:异常的处理
异常分两种大的异常类型,运行时异常和受检查异常. 用户既可以使用系统的异常类来处理异常信息,也可以创建系统的异常类的子类来自定义异常,这种方式比较灵活,虚拟机可以报出自己设置的异常信息,清楚明白. 1 ...
- logstash_agent.conf 语法注意事项
编写配置文件时要注意语法,如新版本的logstash对参数host变更为hosts,去除了port参数等. [root@localhost logstash]# cat logstash_agent. ...
- Mybatis SqlSessionTemplate 源码解析
As you may already know, to use MyBatis with Spring you need at least an SqlSessionFactory and at le ...
- make clean-kernel && make kernel
当在kernel下使用全编译指令后,回到主目录编译仍然有错,那么需要:在 kernel/include/config:删去该文件夹 make clean-kernel && make ...
- linux 查看程序是否运行
命令格式:ps -ax|grep program_name 如查看包含python的程序是否运行: ps -ax|grep python ? Sl : python ToServer.py pts/ ...
- 同步synchronized用法
今天在高人的指导下,对同步synchronized用法有了更高一层的理解,非常感谢他的无私奉献.在此把代码贴出来方便日后查阅. publicclass SfServlet { privatestati ...