排序是开发过程中被经常使用的操作。
作为开发者,由于自己的不小心,可能会使自己掉进排序的一个小陷阱。
那么这个小陷阱是什么呢?
直接上实例代码,看完代码大家就明白了。
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqGroupByExp
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public int ClassId { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Student> studentList = new List<Student>();
studentList.Add(new Student() { Id = 1, Name = "zhangy", Age = 23, Sex = "girl", ClassId = 1 });
studentList.Add(new Student() { Id = 2, Name = "yul", Age = 21, Sex = "boy", ClassId = 2 });
studentList.Add(new Student() { Id = 3, Name = "wsp", Age = 25, Sex = "girl", ClassId = 2 });
studentList.Add(new Student() { Id = 4, Name = "songl", Age = 22, Sex = "girl", ClassId = 1 });
studentList.Add(new Student() { Id = 5, Name = "wuj", Age = 23, Sex = "boy", ClassId = 2 });
studentList.Add(new Student() { Id = 6, Name = "liuy", Age = 20, Sex = "boy", ClassId = 1 });
studentList.Add(new Student() { Id = 7, Name = "wengj", Age = 24, Sex = "girl", ClassId = 2 });
studentList.Add(new Student() { Id = 8, Name = "lipo", Age = 22, Sex = "boy", ClassId = 1 });
Console.WriteLine("*******************************************************************");
Console.WriteLine("原始数据:");
foreach (var s in studentList)
{
Console.WriteLine(" Id = " + s.Id + ", "+
" Name = " + s.Name + ", "+
" Age = " + s.Age + ", "+
" Sex = " + s.Sex + ", "+
" ClassId = " + s.ClassId);
}
Console.WriteLine("*******************************************************************");
Console.WriteLine();
var studentOrderedList1 = studentList.OrderBy(it => it.ClassId);
var studentOrderedList2 = studentOrderedList1.OrderBy(it => it.Age);
Console.WriteLine("*******************************************************************");
Console.WriteLine("两次使用OrderBy排序后的结果:");
foreach (var s in studentOrderedList2)
{
Console.WriteLine(" Id = " + s.Id + ", " +
" Name = " + s.Name + ", " +
" Age = " + s.Age + ", " +
" Sex = " + s.Sex + ", " +
" ClassId = " + s.ClassId);
}
Console.WriteLine("*******************************************************************");
Console.WriteLine();
var studentOrderedList = studentList.OrderBy(it => it.ClassId).ThenBy(it => it.Age);
Console.WriteLine("*******************************************************************");
Console.WriteLine("先使用OrderBy排序,再使用ThenBy排序后的结果:");
foreach (var s in studentOrderedList)
{
Console.WriteLine(" Id = " + s.Id + ", " +
" Name = " + s.Name + ", " +
" Age = " + s.Age + ", " +
" Sex = " + s.Sex + ", " +
" ClassId = " + s.ClassId);
}
Console.WriteLine("*******************************************************************");
Console.WriteLine();
}
}
}
代码中先定义学生列表studentList并向列表添加8条示例数据,接着使用两种方式对studentList列表进行排序并输出结果。
下面重点说说这两种排序。
排序1:使用OrderBy对集合进行两次排序,第一次按照学生的ClassId排序,第二次按照学生的Age排序。
排序2:使用OrderBy+ThenBy对集合进行排序,同样是先按照学生的ClassId排序,再按照学生的Age排序。
那么,问题来了,上面所述的两种排序方法得到的结果相同吗?
答案:自己往下看,下面是代码的执行结果。
从结果可以了解到:两种排序方法的结果并不相同。
下面对结果做简单的分析。
对于排序1:先按照学生的ClassId排序得到集合studentOrderedList1,此时集合中数据的显示顺序由学生的ClassId来决定。接着,再对集合studentOrderedList1中的数据按照学生的Age来排序,得到集合studentOrderedList2 ,此时集合中数据的显示顺序由学生的Age来决定,所以当我们输出集合studentOrderedList2 中的数据时,发现显示顺序由Age决定而与ClassId无关。也就是说,使用OrderBy对集合进行多次排序后,得到的结果中的数据的顺序由最后一次的排序来决定,后次排序覆盖了前次排序。
对于排序2:但是,我们在开发中,经常需要先对集合按照某个字段排序,排序后,再在不影响前次排序结果的条件下按照另一个字段来排序,也就是说最终数据的排列顺序由多个字段来决定时,我们就可以使用OrderBy+ThenBy的方式来实现。例子中使用OrderBy+ThenBy排序得到的最终结果便是由ClassId+Age两个字段来决定的,所有数据先按照ClassId排序,ClassId相同的数据再按照Age来排序。
分析完实验结果,我们来说说文章一开始提到的那个小陷阱吧。
开发时我们往往想要的排序效果正是排序2所达到的效果,但是由于自己考虑不周到,可能会错误的认为排序1同样能达到我们的效果,于是在代码中错误的使用排序1来达到我们想要的效果,结果可想而知了。
这里的小陷阱,与其说是排序的小陷阱,还不如说是认识上的小陷阱,你说是吗。
原文:http://blog.csdn.net/yl2isoft/article/details/24127555