LINQ实际上是基于扩展方法和Lambda表达式的,理解了这一点就不难理解LINQ。任何LINQ查询都能通过调用扩展方法的方式来替代,如下面的代码所示:
var personWithCompanyList=from person in personList select new{
PersonName=person.Name,CompanyName=person.CompanyID==0?
"Micro":"Sun"};
foreach(var item in personWithCompanyList)
{
Console.WriteLine(string.Format("{0}\t:{1}",item.PersonName,
item.CompanyName));
}
在这个查询语句中,通过命名初始化的方式投影出了一个新的类型,它包含属性PersonName和CompanyName,其中,CompanyName通过一个三元运算符进行赋值。要理解上面的查询,我们可以查看本例的另外一种用法,那就是直接调用扩展方法Select,并且为Select方法传入一个Lambda表达式,代码如下所示:
foreach(var item in personList.Select(person=>new{PersonName=
person.Name,CompanyName=person.CompanyID==0?"Micro":"Sun"}))
{
Console.WriteLine(string.Format("{0}\t:{1}",item.PersonName,
item.CompanyName));
}
针对LINQ设计的扩展方法大多应用了泛型委托。System命名空间定义了泛型委托Action、Func和Predicate。可以这样理解这三个委托:Action用于执行一个操作,所以它没有返回值;Func用于执行一个操作并返回一个值;Predicate用于定义一组条件并判断参数是否符合条件。Select扩展方法接收的就是一个Func委托,而Lambda表达式其实就是一个简洁的委托,运算符“=>”左边代表的是方法的参数,右边的是方法体。
在上面的需求中,我们通过直接调用扩展的方式来使用Lambda表达式,这样既完成了要求功能,也减少了一行代码。所以,在实际的工作中,我们应该灵活运用这种方式。下面再举几个这样的例子。
调用Where扩展方法,查找出"Sun"公司的员工:
foreach(var item in personWithCompanyList.Where(p=>p.CompanyName=="Sun"))
{
Console.WriteLine(item.PersonName);
}
输出为:
Mike
Steve
调用OrderByDescending扩展方法,针对PersonName排序:
foreach(var item in personList.OrderByDescending(person=>person.Name))
{
Console.WriteLine(item.Name);
}
输出为:
Steve
Rose
Mike