在了解LINQ语句之前我们有必要先回顾一下扩展方法:
这是一个简单的扩展方法的实例。上述代码又一个我定义的类,还有一个静态类包含一个静态方法。而这个方法就是一个适用于person类的扩展方法。
有一些内容我们需要注意,扩展方法必须为静态的公用的且包含在一个不可为嵌套类型的静态类里。
扩展方法当然也可以作为一个外部静态方法实现相同的操作,毕竟扩展方法并不能让我们访问所要扩展类的私有成员。但是扩展方法还是给我们提供了一种一致以的访问类成员方法相同的方式访问外部方法。这在智能感知的运用下相当有好处。
接下来简单一点让我们先看一个LINQ语句运用的例子
在这个小程序中我使用了LINQ语句查询了列表中的年龄小于21的实例成员,我们可以看到LINQ语句非常类似于SQL语句。他们最大的区别仅在于LINQ语句的select语句放在了最后。这样做据我所知是为了智能感知的需要。
在我们的代码中我们简单了使用了这种类似于SQL语句的语法,但是编译器会修改我们的查询语句以扩展方法的方式实现这个查询语句。
正如上面看到的我在this后面指定扩展的类名,如果我以接口的形式替换类名。那么顺理成章的扩展方法就可以被我们视为凡是实现了该接口的类的成员函数。接下来的代码我将使用扩展方法来实现上述代码的查询操作:
在用扩展方法时我使用了扩展方法的泛型版本。从运行结果来看使用LINQ语句以及使用扩展方法实现了相同的效果。这并不让人感到惊讶,因为编译器也会用扩展方法来替代我们所使用的LINQ语句。LINQ为实现了IEnumerable<T>接口的类提供了许多扩展方法。这样也就意味着我们的LINQ查询语句多用于实现了IEnumeable接口的类型,比如数组等等。虽然扩展方法声明为静态的,但是我们仍然需要使用实例化的类来调用。而不是使用类名。
我们首先分析一个LINQ扩展方法的例子:
我们可以看到在上个代码中所使用的Where()泛型方法的原型,首先从返回值我们可以明确这个扩展方法返回一个实现了IEnumerable接口的类型,那么我们就可以在接下来的代码中使用foreach语句遍历返回值。扩展方法的第一个参数指定了被扩展的类类型,即实现了IEnumerable接口的类。当然我们无法对这个参数进行什么有效的操作,当我们把这个方法视为一个实例扩展方法时。第二个参数是一个泛型委托,在这里我们传递一个方法,传入参数是一个TSource类型,而返回值是一个bool类型,在对泛型方法的操作时,我们将看到大量的Lambda表达式。利用Lambda表达式能减去相当多实例化委托的麻烦。而且Lambda简洁明了的优点也在这里表现的淋漓尽致。那么接下来的函数体就没有什么好说的了,根据传入的Lambda表达式进行处理,利用yield return语句返回一个迭代器。以方便我们在随后对数据的遍历操作。