不管进行何种类型的项目开发,都不可避免的要和数据打交道。而数据的来源又是多样化的,比如内存中的一个集合、数据库、XML文件、Execl表格等等。但是不管是什么数据源,都要实现对数据的操作:查询、排序等等。这些操作的实现方式会因数据源的不同而不同。因为不统一,没有一个普世标准,必然会在开发上给开发人员造成麻烦。那么这个问题怎么解决呢?在.NET 3.5 中引入了一项新的技术——LINQ。
LINQ(Language Integrated Query)语言集成查询。它为查询各种数据源提供了一个同样的接口。通过这个接口,查询各种数据源可以使用近乎一致的方式和语法。既然是一个接口,那么就有接口的调用者和提供者。接口的调用者通常是应用程序,对它们来说,接口的使用方式是一致的。对于接口的提供者,则根据各种不同的数据源有着各自不同的实现(这一点个人感觉和多态是一样的)。根据数据源的不同,LINQ也产生了相应的分支:LINQ to Objects、LINQ to SQL、LINQ to XML、LINQ to Entities、LINQ toExcel等等。
那么,它到底使用了什么技术才能提供统一的接口?因为LINQ使用了以下几个关键技术
咱们来看一下从非泛型委托到LINQ中使用委托的演化过程
非泛型委托:public delegate bool Predicate(string obj);在该定义中,入口参数的类型是明确的,所以,当类型改变以后就需要重新定义一个委托来代表这个方法,代码的复用率不高。
泛型委托: public delegate bool Predicate<T>(Product obj);在该定义中,使用了泛型,可以应对上一定义中不能解决的问题。
返回值也定义为委托:public delegate TResult GeneralMehtod<in T out TResult>(T arg);在这个定义中,干脆将返回值类型也作为泛型来定义,这样的话,返回值类型就不再局限于bool类型了。当然,这个时候方法名也改为了GeneralMethod更为合适。
多个参数的委托:public delegate TResult GeneralMethod<in T,in T2...in T5>(T arg);由上一个委托类推,还可以批量定义委托。
LINQ中的委托:Func<TResult>;在LINQ中,方法名不叫GeneralMethod ,而叫Func。
Func<T1,T2...T8,TResult>;在mscorlib.dll程序集中的System命名空间下定义了含有最多8个参数的委托。
Func<T9,T10...T16,TResult>;在System.Core.dll中的System命名空间下定义了含有最多16个参数的委托。
首先,扩展方法所在的类型要为静态类;其次,被扩展的类型要为方法列表的第一个参数的类型,并且前面要加上this关键字;还有关于代码风格第一个约定:扩展方法所在的类型以Extension作为结尾(这个就是约定优于配置)。
匿名方法的语法很简单:使用delegate关键字进行声明,后面跟随方法的参数列表,花括号中编写方法体,ok了。
相比匿名方法,lambda表达式省略了delegate关键字,也省略了参数类型。“=>”右边是方法体,如果方法体超过一行,就需要加上花括号。
LINQ的出现统一了操作各类数据源的接口,使得开发的难度和复杂度降低。还有很多细节没有在此说明,在接下来的博客中会使用一个实例来展示LINQ的重要内容。