LINQ 扩展方法





4.00/5 (3投票s)
对通用集合调用 LINQ 扩展方法。
引言
在这篇简短的文章中,我们将介绍 .NET Framework 3.5 版本中引入的 System.Linq
命名空间中定义的一些扩展方法。
背景
迭代集合并分析其中包含的数据是编程中常见的任务。 LINQ 扩展方法是 .NET 3.5 开发人员可用于加速和简化集合操作的工具之一。
Using the Code
我们可以假设在代码的某个地方,已经用数据填充了一个 System.Collections.Generic
字典。字典中的每个键都是一个用户名 string
,每个值都是一个泛型列表对象,其中包含与每个用户相关的整数值。
Dictionary<string, List<int>> Users = new Dictionary<string, List<int>>();
Users.Add("Joe, Smith", new List<int>() { 20, 18, 12});
Users.Add("Jane, Doe", new List<int>() { 20, 20, 20, 18 });
Users.Add("Tom, Beck", new List<int>() { 14, 15, 20, 17 });
我们可能对从泛型字典中提取所有用户名到一个单独的泛型列表感兴趣,如下所示
List<string> lstUserNames = Users.Keys.ToList<string>();
类似地,我们可以从泛型字典中提取所有用户数据列表到一个单独的泛型列表中,其中每个元素都是它自己的泛型列表
List<List<int>> lstUserData = Users.Values.ToList<List<int>>();
我们可能需要对构成每个用户数据列表的所有数据元素求和。 为此,我们可以调用 Aggregate
扩展方法,该方法可以应用于实现 IEnumerable<TSource>
的对象,并接受一个 delegate
作为参数,如下所示
List<int> lstSums = new List<int>();
foreach (List<int> l in lstUserData)
{
lstSums.Add(l.Aggregate((sum, elmnt) => sum + elmnt));
}
在上面的 for
循环中,我们迭代 lstUserData
泛型列表的每个元素,其中每个元素恰好是它自己的整数值泛型列表。 注意用于表示作为参数传入的 delegate
的 Lambda 表达式。
Aggregate
扩展方法的 delegate
接受两个整数参数并返回一个表示两个输入参数之和的整数值。 Aggregate
扩展方法循环遍历列表的每个元素,并执行由传入的 delegate
返回的操作。
或者,我们可以使用匿名方法编写内联 delegate
,而不是使用 lambda 表达式
foreach (List<int> l in lstUserData)
{
lstSums.Add(l.Aggregate(delegate(int sum, int elmnt) { return sum + elmnt;} ));
}
可以在上面的列表上调用其他扩展方法。 例如,我们可以调用一个方法来计算列表中值的平均值,检查列表中每个元素是否满足某个布尔条件,以及检查列表中是否有任何元素满足某个条件
List<double> lstAvges = new List<double>();
List<bool> lstAllBool = new List<bool>();
List<bool> lstAnyBool = new List<bool>();
foreach (List<int> l in lstUserData)
{
lstAvges.Add(l.Average());
lstAllBool.Add(l.All(elmnt => elmnt >= 14));
lstAnyBool.Add(l.Any(elmnt => elmnt == 20));
}
All
扩展方法迭代列表,如果所有元素都满足指定的布尔条件,则返回 true
。 在上面的示例中,如果列表中的所有元素都大于或等于 14
,则返回 true
。
Any
扩展方法迭代列表,如果任何元素满足指定的布尔条件,则返回 true
。 在上面的示例中,如果列表中的任何元素的值为 20
,则返回 true
。
当定义输入 delegate
而不是更简单的 lambda 表达式时,可以使用匿名方法来编写上面的代码
foreach (List<int> l in lstUserData)
{
lstAvges.Add(l.Average());
lstAllBool.Add(l.All(delegate(int elmnt) { return elmnt >= 14; }));
lstAnyBool.Add(l.Any(delegate(int elmnt) { return elmnt == 20; }));
}
lstSums
泛型列表(其中每个元素都是字典中每个用户数据列表中的所有元素的总和)可用于调用 OrderBy
扩展方法,该方法按升序对元素进行排序
var sums = lstSums.OrderBy(elmnt => elmnt);
然后可以将生成的排序列表绑定到 GridView
控件并在窗体上显示
GridView1.DataSource = sums;
GridView1.DataBind();
GridView1.HeaderRow.Visible = false;
关注点
如上面的代码所示,当作为参数传入时,Lambda 表达式简化了 delegate
的定义。 此外,LINQ 扩展方法(例如本文中调用的方法)提供了快速简便的方法来操作集合中的数据,并根据简单定义的条件返回这些集合的子集。
历史
- 2008 年 6 月 16 日:初始发布