【写给Cpp选手的C#教程】LINQ篇
个人觉得LINQ非常的神奇,从表面上看,像是在编程语言中插入了SQL语句。但又感觉,如果从一个大的集合中进行关键对象的查找的话,好像也确实不失为一种好方法?
个人对这种机制很好奇,所以先对他进行学习吧。
查询运算符
不知道他为什么要叫查询运算符,但总体而言是如下这么用的。
string[] names = { "Tom", "Dick", "Harry" };
//下面这个是全写,将会返回Dick和Harry
//IEnumerable<string> ans = System.Linq.Enumerable.Where(names,n=>n.Length >= 4);
IEnumrable<string> ans = names.Where(n => n.Length >= 4);
由此可见,Where接收一个lambda表达式作为具体筛选的方法,其返回值必须是bool类型。
之所以能够用“names.”来进行操作,是因为如Where的查询运算符都是以静态扩展方法实现的,他们都会被解析为Enumerabe类的扩展方法(前提是导入System.Linq库)
流式语法
虽然还没有我之前看到的那么离谱,但这些语句已经有点像SQL语言了。
class Program
{
public static void Main()
{
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> ans = names
.Where(a => a.Contains("a")) //筛选输入序列
.OrderBy(b => b.Length) //排序
.Select(c => c.ToUpper()); //对每个元素进行处理
//ans为{JAY,MARY,HARRY}
}
}
其实一行行看下来,好像也没什么。就是一个链式的函数而已。函数从上到下,每一个函数的返回值都会作为对象进行下一个函数的调用。
查询表达式
最离谱的东西出现了,像是在C#之中嵌套SQL语句的东西。不过看书上说,其实来源于LISP、Haskell这样的函数式编程语言中的列表推导功能。
class Program
{
public static void Main()
{
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
//IEnumerable<string> ans = names
// .Where(a => a.Contains("a"))
// .OrderBy(b => b.Length)
// .Select(c => c.ToUpper());
IEnumerable<string> ans =
from n in names //通过这样的语句,遍历列表中的所有元素
where n.Contains("a")
orderby n.Length
select n.ToUpper();
//ans为{JAY,MARY,HARRY}
}
}
一个完整的查询以from开始,中间可以以任意顺序使用where、orderby、let以及join,最终以select或者group结尾。
LINQ查询语法看上去很像SQL语法,但其实是完全不同的。
比如LINQ中变量必须在声明之后使用,而在SQL之中,SELECT自居可以在FROM定义前引用表的别名。
LINQ的子查询实际上是另一个C#表达式,不需要专门的语法。
LNQ查询中对元素的处理过程和使用的语句顺序有关,而SQL查询中是按照固定的流程进行处理的(存疑)
混合查询
我们竟然可以把流式查询和表达式查询混合在一起:
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
string first = (from n in names orderby n.Length descending select n).First(); //Harry
混合查询有限制,每一种查询语法组件必须是完整的(从from开始,以select或group结束)
浙公网安备 33010602011771号