LINQ中的聚合函数最常用的有Sum(),Average(),Max(),Min()。顾名思义,这些聚合函数分别用于获取记录集中的“总和”、“平均数”、“最大值”、“最小值”。这些函数的使用也非常简单,下面举例介绍。
1) Sum()
List<int> intInList = new List<int>() { 1, 3, 3, 2, 7, 8, 4, 5, 6, 3, 9 }; int sumOfList = intInList.Sum(); Console.WriteLine(sumOfList);
2) Average()
List<int> intInList = new List<int>() { 1, 3, 3, 2, 7, 8, 4, 5, 6, 3, 9 }; double averageOfList = intInList.Average(); Console.WriteLine(averageOfList);
3)Max()
List<int> intInList = new List<int>() { 1, 3, 3, 2, 7, 8, 4, 5, 6, 3, 9 }; int maxOfList = intInList.Max(); Console.WriteLine(maxOfList);
4)Min()
List<int> intInList = new List<int>() { 1, 3, 3, 2, 7, 8, 4, 5, 6, 3, 9 }; int minOfList = intInList.Min(); Console.WriteLine(minOfList);
上面介绍了常用聚合函数的用法,注意我用的是int型的List,如果我们有一个自定义的类该如何使用呢?更确切的说,比如现在我有一个Person类,里面有FirstName和LastName属性,那么当我调用Min()函数时,会发生什么?如下面的代码所示:
public class Person { public string FirstName; public string LastName; } class Program { static void Main(string[] args) { List<Person> personInList = new List<Person>() { new Person() { FirstName = "Jonh", LastName = "Liu" }, new Person() { FirstName = "Sara", LastName = "Guo" }, new Person() { FirstName="Marttin", LastName = "Zeng" }, new Person() { FirstName="Sccot", LastName= "Jiang" } }; Person minPerson = personInList.Min(); Console.WriteLine(minPerson.FirstName); } }
事实上,上面的代码会有一个运行时异常:
Unhandled Exception: System.ArgumentException: At least one object must implement IComparable. at System.Collections.Comparer.Compare(Object a, Object b) at System.Linq.Enumerable.Min[TSource](IEnumerable`1 source) at ConsoleApplication1.Program.Main(String[] args) in c:\D\others\Code\Test\ConsoleApplication1\Program.cs:line 51 Press any key to continue . . .
原因是.NET根本不知道如何判断Person类从而获取它的最小值。List<int>之所以能成功调用是因为.net知道如何去比较int型数据,从而求出最小值。为了让.NET知道如何去比较两个Person,从而决定他们的大小我们需要让Person类实现一个名为IComaparable<T>的接口,该接口定义了如何去判断两个对象的大小的方法。我们把Person类做如下修改:
public class Person:IComparable<Person> { public string FirstName; public string LastName; public int CompareTo(Person obj) { return this.FirstName.CompareTo(obj.FirstName); } }
上面的代码实现了让Person类通过FirstName属性进行比较,下面的代码就找出了personInList中的FirstName最小所对应的那个Person对象:
Person minPerson = personInList.Min(); Console.WriteLine(minPerson.FirstName);
当然,如果我们不想去修改Person类,因为Person类很可能是第三方已经写好的类,我们没办法修改一个已经打包好的dll文件,那么我们还可以调用Min()的重载函数:
public static TResult Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
这里,可以向Min()中传入一个代理,该代理指定了如何对Person排序,如下面的代码:
string minFirstName = personInList.Min(p => p.FirstName); Console.WriteLine(minFirstName);
时间: 2024-12-26 16:33:05