导读:     1 预备知识

2 神马是LINQ

3 LINQ牛b的地方

4 剖析LINQ

5 LINQ扩展知识

预备知识: ① 扩展方法

.net framework 3.5中提供了扩展方法,何为扩展方法,举例如下:

假如有个string类型,我要为它写extension,那么应该如下:

public static class Extension
{ public static void ExtensionMethod(this string str) { Console.WriteLine("It's a extension for {0}", str);}
}

需要注意,class和method都是static的,然后注意参数列表,有个“this”,这是关键,多个参数的时候,在第一个参数前添加。 写好之后,就可以为所欲为了,例如:

class Program
{ static void Main(string[] args) { string str = "test";         str.ExtensionMethod();         Console.ReadLine(); }
}

②:lambda(λ)表达式   这个表达式说简单其实很简单,但复杂是真复杂,原因是在.net中,用到的地方太多了。一言以蔽之,arg-list => expr-body, 左边是参数,右边是方法体,操作符叫做Goes to。 举例如下:

static void Main(string[] args)
{Func<int, int> b = a => { return a + 1; }; Console.WriteLine("Lambda :"+b(1));Console.ReadLine();
}

注:Func是一种委托,输出结果是2。

也可简化下,一秒变格格,我变~:

static void Main(string[] args)
{Func<int, int> b = a =>  a + 1;Console.WriteLine("Lambda :"+b(1));Console.ReadLine();
}

是不是更简洁了,因为lambda的强大!

下面还原为传统的方式,格格变bra~~

class Program
{delegate int DelegateLambda(int arg);static void Main(string[] args){DelegateLambda delegateLambda = new DelegateLambda(AddMethod); int b = delegateLambda(1);Console.WriteLine("Lambda: " + b); Console.ReadLine();}static int AddMethod(int arg){int result = 0;result = arg + 1; return result;}
}

在这段代码中,来对号入座,DelegateLambda 是自己定义的委托,对应了func;新写了个方法,AddMethod,这个方法对应了=>右边的方法体(其实是一个匿名函数,.net 3.5中的东东) ,方法体所用到的参数对应=>左边的那个a。

③:必要的sql知识:select , from , where ,orderby, groupby,。。。balabalabala&*$#@&.

④: .net framework 3.5以上版本!

神马是LINQ:

语言集成查询 (LINQ-Language Integrated Query的简称) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上。 借助于 LINQ,查询现在已是高级语言构造,就如同类、方法、事件等等。

对于编写查询的开发人员来说,LINQ 最明显的“语言集成”部分是查询表达式。 查询表达式是使用 C# 3.0 中引入的声明性查询语法编写的。 通过使用查询语法,甚至可以使用最少的代码对数据源执行复杂的筛选、排序和分组操作。 使用相同的基本查询表达式模式来查询和转换 SQL 数据库、ADO.NET 数据集、XML 文档和流以及 .NET 集合中的数据。

LINQ牛b的地方:

linq的牛逼之处在于,可以非常灵活的操作集合类对象(泛指继承自IEnumerable接口的对象),xml对象,以及数据库对象,linq上升到语言角度,可以做到像操作T-sql那样灵活自如而不失优雅,使我们更多的关注于业务逻辑而不至于为业务实现而费神。

linq,其实就是DSL,优雅的实现,真的是你秒杀各种需求的必备良药哦~

(DSL的编译过程应该是:DSL->Common c# code ->msil)

吹了半天牛b,来,来个实例,体会下linq这把利剑:

        static void Main(string[] args) { List<int> intArr = new List<int> {5,2,7, 23,7,9,15}; var result = from i in intArr where (i > 7) select i;foreach (var ele in result) { Console.WriteLine(ele);} Console.ReadLine(); } 

筛选的结果输出后为:23 9 15 是不是很有写sql语句的感觉?嘿,又要变格格了~~

        static void Main(string[] args){ List<int> intArr = new List<int> {5,2,7, 23,7,9,15}; var result = intArr.Where(i => i > 7) .Select(i=>i); foreach (var ele in result) { Console.WriteLine(ele); } Console.ReadLine(); }

输出的结果是一样一样滴,为什么呢,再想想lambda表达式和扩展方法,(*^__^*) 好,再来一个:

        static void Main(string[] args) { List<int> intArr = new List<int> {5,2,7, 23,7,9,15}; var result = intArr.Where(i => i > 2) .OrderByDescending(i=>i) .Select(i=>i); foreach (var ele in result) { Console.WriteLine(ele); } Console.ReadLine(); }

输出结果是:23 15 9 7 7 5

这段代码是降序排列的代码,是不是感觉还行~~,但是还有两个7,比较烦人呢,好,去掉:

        static void Main(string[] args){ List<int> intArr = new List<int> {5,2,7, 23,7,9,15}; var result = intArr.Where(i => i > 2) .OrderByDescending(i=>i).Select(i=>i).Distinct();foreach (var ele in result) { Console.WriteLine(ele); } Console.ReadLine(); }

输出结果为:23 15 9 7 5 怎么样,linq是不是不错呢,要是觉得这有些幼稚,不要捉急,还有各种操作xml的linq和数据库的呢,再这里就不写连接查询了,算是留个小悬念,要有兴趣最好写几个联合查询。

*剖析LINQ:(这个是重点,帮助你更好理解linq的幕后) linq如此强大,究竟编译器在背后干了些什么见不得人的勾当啊,其实,幕后真没有什么神奇的东东,如果反编译的话(好吧,其实我看不太懂msil ^^),你会发现,真的可以还原为普通的c#代码,这也就证明了linq的编译:DSL->common c# ->msil模式。 闲话不多说,还是用代码来说明一切:

首先定义一个Person类

public class Person
{//姓名      public string name { get; set; } //年龄      public int age { get; set; }//婚姻状况      public bool isMarry { get; set; }
}

初始化一些人。现在tc要跨省他们中大于20岁的人~~传统的做法是这样:

        static void Main(string[] args) { IList<Person> persons = new List<Person> (); IList<Person> result = new List<Person>();persons.Add(new Person { name = "狗剩", age = 22, isMarry = false }); persons.Add(new Person { name = "二蛋子", age = 28, isMarry = true });persons.Add(new Person { name = "大黄", age = 10, isMarry = false }); persons.Add(new Person { name = "傻蛋", age = 30, isMarry = true }); persons.Add(new Person { name = "小李子", age = 19, isMarry = false });foreach (Person p in persons) { if (p.age > 20) result.Add(p); }foreach (Person p in result) { Console.WriteLine(p.name); } Console.ReadLine(); }

输出结果是:狗剩 二蛋子 傻蛋

现在相关部门说了,要跨省一些结婚的,那么我们是不是还要重写这个方法呢,真tmd烦人啊,要是LD又说了,要找身高大于180cm的(当然这里我懒,没定义这个属性),我还要重写啊,LD真的好烦哎。好吧,你的老大说了,其实我们可以简单点,if里边不就是一个条件吗,我们可以单独写,是不是更好呢 于是我们可以这样来: 先定义一个委托 delegate bool Condition(Person p); 然后写将要委托的方法,领导不是说要找结了婚的吗:

class Program
{ public delegate bool Condition(Person p);static void Main(string[] args) { IList<Person> persons = new List<Person> (); IList<Person> result = new List<Person>();persons.Add(new Person { name = "狗剩", age = 22, isMarry = false }); persons.Add(new Person { name = "二蛋子", age = 28, isMarry = true }); persons.Add(new Person { name = "大黄", age = 10, isMarry = false }); persons.Add(new Person { name = "傻蛋", age = 30, isMarry = true }); persons.Add(new Person { name = "小李子", age = 19, isMarry = false });result = SearchPerson(new Condition(ConditionIsMarry),persons);foreach (Person p in result) { Console.WriteLine(p.name); } Console.ReadLine(); }public static IList<Person> SearchPerson(Condition condition, IList<Person> persons) { IList<Person> result = new List<Person>();foreach (Person p in persons) { if (condition(p)) result.Add(p);}return result; }public static bool ConditionIsMarry(Person p) { if (p.isMarry) return true; return false; }
}

这样我们可以写很多个查询条件,想用哪个用哪个,这样不用很多修改,更有利于扩展。接下来,你懂得,又要变了,还记得前面提到的匿名方法吗,好了,现在用到了,我们委托一个匿名方法:

static void Main(string[] args)
{ IList<Person> persons = new List<Person> (); IList<Person> result = new List<Person>();persons.Add(new Person { name = "狗剩", age = 22, isMarry = false }); persons.Add(new Person { name = "二蛋子", age = 28, isMarry = true }); persons.Add(new Person { name = "大黄", age = 10, isMarry = false }); persons.Add(new Person { name = "傻蛋", age = 30, isMarry = true }); persons.Add(new Person { name = "小李子", age = 19, isMarry = false });result = SearchPerson(delegate(Person p) { return p.isMarry == true; }, persons);foreach (Person p in result) { Console.WriteLine(p.name); } Console.ReadLine();
}

这段代码只修改了一句话,用到了一个匿名方法,方法体是判断是否结婚。但是有没有感觉有点不伦不类呢?啥玩意啊,一个语句里边里加了一个方法?fxxk啊!不能着急,都是优雅的人好吗?还记得之前说的lambda表达式吗,没错,来了,只改一句话,变了哦:

result = SearchPerson(p =>p.isMarry==true, persons);

优雅了没呢? 这远远不算优雅,为啥呢,每次我用到查找方法的时候,我都要用SearchPerson方法,我还要调用,真心烦啊,好吧,预备知识中的扩展方法还记得不?嘿嘿,来了:把SearchPerson方法写为扩展方法,这样岂不是以后所有的Ilist<Person>类型,都可以随便用了?为了优雅,把这个方法改名字,改为Where见名知意,而且通用,改写为:

public static class Helper
{public delegate bool Condition(Person p);public static IList<Person> Where(this IList<Person> persons, Condition condition){IList<Person> result = new List<Person>();foreach (Person p in persons) { if (condition(p)) { result.Add(p); } }return result;}
}

然后呢,在main方法里边就可以为所欲为的使用where方法了:

static void Main(string[] args)
{ IList<Person> persons = new List<Person> (); IList<Person> result = new List<Person>();persons.Add(new Person { name = "狗剩", age = 22, isMarry = false }); persons.Add(new Person { name = "二蛋子", age = 28, isMarry = true }); persons.Add(new Person { name = "大黄", age = 10, isMarry = false }); persons.Add(new Person { name = "傻蛋", age = 30, isMarry = true }); persons.Add(new Person { name = "小李子", age = 19, isMarry = false });result = persons.Where(p => p.isMarry == true);foreach (Person p in result) { Console.WriteLine(p.name); } Console.ReadLine();
}

咦,where?sql?linq?恩,有点像了,可where中,可没说一定要是person泛型的啊,好,再变,集合类都是继承与IEnumerable接口的,而person类型,也可以改为泛型T,这样一来所有的集合类是不是随便用where了?接着改:

public static class Helper
{ public delegate bool Condition<T>(T p);public static IEnumerable<T> Where<T>(this IEnumerable<T> items, Condition<T> condition) { foreach (T t in items) { if (condition(t)) { yield return t; } } }
}

在main中可以这样写:

static void Main(string[] args)
{ IList<Person> persons = new List<Person>();persons.Add(new Person { name = "狗剩", age = 22, isMarry = false }); persons.Add(new Person { name = "二蛋子", age = 28, isMarry = true }); persons.Add(new Person { name = "大黄", age = 10, isMarry = false }); persons.Add(new Person { name = "傻蛋", age = 30, isMarry = true }); persons.Add(new Person { name = "小李子", age = 19, isMarry = false });var result = persons.Where(p => p.isMarry == true);foreach (var p in result) { Console.WriteLine(p.name); } Console.ReadLine();
}

这样一来,所有的继承于IEnumerable的类型,就都可以用where方法了,在这里还要记住一点,var是.net中的隐藏类型,也就是说在运行时的时候,编译器自动根据赋值语句判断var的类型,但是以下语句是错误的 var a;var类型一定要初始化,否则编译器不能判断。然后这里还有一个yield,这大概是framework 2.0开始使用的关键词,作用是返回迭代器中所有符合条件的对象。接下来可以如法炮制,写select,和groupby之类的。感谢ms,所有的这些方法,都给写好了,ms还给他起了个名字叫:LINQ。

LINQ扩展知识: 上面基本上是linq 对于object的操作,其实linq分好几块,按照大类分:Linq to sql,linq to object ,linq to xml.对于其他的两大类,在此就不一一赘述了,理解了一种即可触类旁通。

其实linq的学习,这些知识只是刚刚入门,想学好linq除了多多练习之外,一定要深刻得剖析linq背后的机制,只有这样才能理解深刻。否则做再多的练习都是机械性的重复,以后也根本不能很好驾驭linq。 好了,到此为止吧。

老规矩,所有的代码,都是上机跑过的~~

转载于:https://www.cnblogs.com/craoy/archive/2012/04/17/2453770.html

自己的Linq学习心得相关推荐

  1. Socket学习心得

    最近才开始接触socket,分享一下学习心得,如果发现其中任何错误,欢迎高手们直接指出. 1.按惯例先来介绍下socket       Windows 中的很多东西都是从Unix领域借鉴过来的,Soc ...

  2. Java EE学习心得

    –Java EE学习心得   1.    称为编程专家的秘诀是: 思考-----编程--------思考------编程--.. 编程不能一步到位,不能一上来就编,必须先思考如何写,怎样写?然后再编程 ...

  3. Assembly学习心得

    http://blog.csdn.net/etmonitor/ Assembly学习心得 说明: 最近开始准备把学到的.NET知识重新整理一遍,眼过千遍不如手过一遍,所以我准备记下我的学习心得,已备参 ...

  4. 对于mysql存储过程感想_存储过程学习心得

    存储过程学习心得 (2014-12-28 17:28:06) 标签: it 我使用过几次SQL Server,但所有与数据库的交互都是通过应用程序的编码来实现的.我不知到在哪里使用存储过程,也不了解实 ...

  5. 好程序员Web前端教程分享Vue学习心得

    为什么80%的码农都做不了架构师?>>>    好程序员Web前端教程分享Vue学习心得,Vue是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向 ...

  6. 大学计算机课英语心得体会,关于计算机网络辅助大学英语教学的思考学习心得...

    关于计算机网络辅助大学英语教学的思考学习心得 [摘要]计算机网络辅助教学可以增强学生的学习兴趣,提高他们自觉学习的能力,因而得到了大多数学生的认可,取得了比较显著的成效.计算机网络辅助教学也对大学英语 ...

  7. 我的MYSQL学习心得(十六) 优化

    原文:我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看 ...

  8. Spring Framework------version4.3.5-----Reference学习心得-----总结

    1.Spring Framework概述: 有很多可用版本,网址http://projects.spring.io/spring-framework/       2.Spring Framework ...

  9. 计算机基础与应用(上)笔记总结,计算机基础学习心得体会范文(通用3篇)

    计算机基础学习心得体会范文(通用3篇) 当我们对人生或者事物有了新的思考时,好好地写一份心得体会,这样可以记录我们的思想活动.那么要如何写呢?以下是小编精心整理的计算机基础学习心得体会范文(通用3篇) ...

最新文章

  1. 结合Android去水印APP谈谈分区存储
  2. hp unix oracle rac节点一磁盘损坏,节点修复
  3. [Scala]集合中List元素转Tuple元素的函数迭代写法
  4. 简述C/S和B/S模式的区别
  5. 如何把自己github博客配置到一个腾讯云购买的自定义域名上
  6. 前端学习(486):css选择器上
  7. 《Python编程从入门到实践》记录之第7章 用户输入(input)和while 循环总结(思维导图)
  8. bootstrap dialog
  9. 第012讲 盒子模型经典应用
  10. 2015阿里数据分析师校招面试经历
  11. python搬家具_Python面向对象实现案例———摆放家具
  12. win10管理员名称更改方法
  13. springboot向word文档插入内容和图片
  14. KubeEdge+Fabedge集成环境搭建教程
  15. 如何撰写品牌故事?品牌故事软文撰写技巧分享
  16. 游戏浅谈1-传奇,跑跑卡丁车
  17. Win7解决telnet不是内部或外部命令的方法
  18. skycc广告群发软件v9.2专业版
  19. 微信开发者工具中使用scss
  20. javamail QQ邮箱发送实例

热门文章

  1. 远程控制软件哪个好用?
  2. SPINE:高拓展性、用户友好的自动化日志解析新神器
  3. 让 Homekit 不再鸡肋,树莓派、 Homebridge 、AC86U 的 Mixture!
  4. 无损视频合并软件有哪些?如何合并视频 1
  5. 15行python代码轻松批量下载()视频~
  6. 桃花院长:如何快速找对象? 告诉你11种方法
  7. 三国杀将灵计算器vue编写
  8. 基于FPGA的扩频系统设计(上)
  9. C实现-小写字母转换为大写字母(具体)
  10. Spring cloud系统架构的淘宝客之二