上节讲到使用linq的查询关键字进行查询,这节讲一下linq查询的另一种方式——linq方法。
使用linq方法语法,必须要会用lambda表达式,配合lambda表达式才能体会到linq的优雅便捷。
linq方法是一系列的扩展方法,对于实现了IEnumerable接口的对象,都可以使用,扩展方法在VS智能提示中显示为一个正方体加一个向下的虚箭头。
对于上节的代码,使用方法语法则可以简洁为一行:
代码语言:javascript复制 int[] vs = { 1, 6, 3, 2, 5 };
var a = vs.Where(v => v > 3);
foreach (var t in a)
{
Console.Write(t);
}
运行结果为:65 使用方法语法的好处是可以直接在原数据后操作,可以使用链式编程实现复杂的查询操作。但是一些情况下查询语法更好用,这个要看开发的需求以及个人喜好。
下面介绍一些常用的linq方法(以下例子基于上述vs数组):
Select
linq方法基本上都要配合lambda表达式,因为linq方法的参数一般都是一个委托,而lambda表达式在填充委托方面有着优雅的特性(不熟悉lambda表达式用法的同学可以回顾往期文章:浅析C#中的Lambda表达式),表达式参数即是每个遍历到的数据。Select()方法用于隐式迭代所有的数据,可以在迭代中对每个数据进行处理:
代码语言:javascript复制var a = vs.Select(v => v);//将所有数据加一并返回
SelectMany()方法用于返回多行结果,它可以在方法中嵌套查询。
Skip,Take
Skip(int i)方法用于跳过前i个元素,相反的,Take(int i)方法用于获取前i个元素
代码语言:javascript复制var a = vs.Skip(2);//运行结果:325
var a = vs.Take(2);//运行结果:16
SkipWhile()和TakeWhile()用于满足条件即停止执行,前者返回剩下的元素,后者返回匹配到的元素,个人觉得这两个方法执行逻辑很绕,有兴趣的可以自己写代码看看效果。 SkipLast(int i)和TaskLast(int i)用于跳过和获取最后的元素。
Concat
concat(IEnumerator<T>)用于将参数拼接在原数据的后面。
代码语言:javascript复制var a = vs.Concat(new List<int>(){7,9,8});//运行结果16325798
Contains
Contains(T t)用于指定其参数是否包含在该数据源中。
代码语言:javascript复制var a = vs.Contains(2);//true
它还有一个重载方法 Contains(T t,IEqualityComparer<T> e),第二个参数用于自定义比较的规则,因为有的时候系统的直接比较法不是我们想要的,所以就需要我们自定义比较规则,这个可以展开来解释一下:它的第二个参数是一个接口,接口里边定义了一个Equals()方法,我们需要自定义一个类实现这个接口,请看代码:
代码语言:javascript复制public class MyClass : IEqualityComparer<int>
{
public bool Equals(int x, int y){
y = y - 2;
return x == y;
}
//该方法是此接口的另一个方法,与当前上下文无关,此处不做说明
public int GetHashCode(int obj){
throw new NotImplementedException();
}
}
代码语言:javascript复制var a = vs.Contains(2, new MyClass());//false
x就是Contains()的第一个参数,y是迭代数据源中的每一个数据,我现在将比较规则改为比较x是否等于y-2,相当于说让比较2是否包含在{-1, 4, 1, 0, 3}中,显然,结果为false。
一般情况下,自定义规则用在比较自定义对象数组或集合中。
OrderBy
OrderBy()用于排序,根据lambda表达式的返回值进行升序排序,它有一个重载,用于自定义排序规则,用法跟Contains()类似。
代码语言:javascript复制var a = vs.OrderBy(c => c);//运行结果 12356
下面我使用它的重载降序排序数据
代码语言:javascript复制public class MyClass : IEqualityComparer<int>, IComparer<int>
{
public int Compare(int x, int y){
return -(x - y);
}
}
再次调用后结果为降序:
代码语言:javascript复制var a = vs.OrderBy(c => c,new MyClass());//运行结果65321
其它
下面简洁介绍一下另一些常用的方法(了解更多linq方法请查阅相关文档):
bool All(),bool Any() | 前者所有元素满足即为true,后者至少一个满足即为true |
---|---|
int Count(),long LongCount() | 两者都是计数,并且可以统计满足条件元素个数,只是返回值不同 |
T Max(),T Min() | 返回最大最小值,可以自定义排序规则(凡是涉及到比较或排序的,都可以自定义规则) |
double Sum() | 求和 |
T ElementAt(),T ElementAtOrDefault() | 获取指定位置上的元素,后者对于访问出错的情况下返回可以将设置的默认值返回 |
本节到此结束...