c#范型List的Sort方法详解

http://blog.csdn.net/fireofstar/article/details/3446393 

.net2005中的范型List类的Sort方法有四种形式,分别是
  1,不带有任何参数的Sort方法----Sort();
  2,带有比较器参数的Sort方法 ----Sort(IComparer<T>)
  3,带有比较代理方法参数的Sort方法----Sort(Comparison<(Of <(T>)>))
  4,带有比较起参数,可以指定排序范围的Sort方法----Sort(Int32, Int32 IComparer(T))
  首先介绍第一种方法,使用这种方法不是对List中的任何元素对象都可以进行排序,List中的元素对象必须继承IComparable接口,并且要实现IComparable接口中的CompareTo()方法,在CompareTo()方法中要自己实现对象的比较规则。详细可以参照如下代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Comparer.SortObject
  5. {
  6.     /// <summary>
  7.     /// List<>.Sort()的测试对象,类自己实现IComparable接口,
  8.     /// 当需要对List中的SortTestObj1对象进行排序时,直接调用
  9.     /// Sort()方法就可以了。
  10.     /// </summary>
  11.     public class SortTestObj1:IComparable
  12.     {
  13.         #region 类字段定义
  14.         private int code;
  15.         private string name;
  16.         #endregion
  17.         public SortTestObj1()
  18.         {
  19.             //
  20.         }
  21.         #region 属性定义
  22.         public int Code
  23.         {
  24.             set { this.code = value; }
  25.             get { return this.code; }
  26.         }
  27.         public string Name
  28.         {
  29.             set { this.name = value; }
  30.             get { return this.name; }
  31.         }
  32.         #endregion
  33.         #region 实现比较接口的CompareTo方法
  34.         public int CompareTo(object obj)
  35.         {
  36.             int res = 0;
  37.             try
  38.             {
  39.                 SortTestObj1 sObj = (SortTestObj1)obj;
  40.                 if (this.code > sObj.code)
  41.                 {
  42.                     res = 1;
  43.                 }
  44.                 else if (this.code < sObj.code)
  45.                 {
  46.                     res = -1;
  47.                 }
  48.             }
  49.             catch (Exception ex)
  50.             {
  51.                 throw new Exception("比较异常", ex.InnerException);
  52.             }
  53.             return res;
  54.         }
  55.         #endregion
  56.     }
  57. }

  第二种带有比较器参数的Sort方法,List中的元素对象不需要继承IComparable接口,但需要额外创建一个对象的比较器,下面的代码中的SortTestObj2类是准备要保存到范型List中的对象,SortTestObj2Camparer 类则是SortTestObj2类的比较器,这个比较起必须继承IComparer<T>接口,并且实现接口中的Compare()方法。详细做法可参照下面的代码。
SortTestObj2类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Comparer.SortObject
  5. {
  6.     /// <summary>
  7.     /// List<>.Sort(IComparer<(Of <(T>)>))的测试对象,类自己没有实现IComparable接口,
  8.     /// 当需要对List中的SortTestObj2对象进行排序时,需要实例化一个SortTestObj2Camparer
  9.     /// 类型的比较器,在比较器中指明排序类型(按Code排序还是按Name排序),然后调用
  10.     /// xxxLst.Sort(SortTestObj2Camparer)方法就可以了。
  11.     /// </summary>
  12.     public class SortTestObj2
  13.     {
  14.         #region 类字段定义
  15.         private int code;
  16.         private string name;
  17.         #endregion
  18.         public SortTestObj2()
  19.         {
  20.             //
  21.         }
  22.         #region 属性定义
  23.         public int Code
  24.         {
  25.             set { this.code = value; }
  26.             get { return this.code; }
  27.         }
  28.         public string Name
  29.         {
  30.             set { this.name = value; }
  31.             get { return this.name; }
  32.         }
  33.         #endregion
  34.     }
  35. }

SortTestObj2Camparer类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Comparer.SortObject;
  5. namespace Comparer.Camparer
  6. {
  7.     [Flags]
  8.     //排序类型定义
  9.     public enum Obj2SortKind { Code, Name }
  10.     /// <summary>
  11.     /// SortTestObj2类排序用的比较器,继承IComparer<>接口,
  12.     /// 实现接口中的Compare()方法。
  13.     /// </summary>
  14.     public class SortTestObj2Camparer : IComparer<SortTestObj2>
  15.     {
  16.         #region 类字段定义
  17.         private Obj2SortKind sortKind;
  18.         #endregion
  19.         #region 构造器
  20.         public SortTestObj2Camparer(Obj2SortKind sk)
  21.         {
  22.             this.sortKind = sk;
  23.         }
  24.         #endregion
  25.         #region IComparer接口比较方法的实现
  26.         public int Compare(SortTestObj2 obj1, SortTestObj2 obj2)
  27.         {
  28.             int res = 0;
  29.             if ((obj1 == null) && (obj2 == null))
  30.             {
  31.                 return 0;
  32.             }
  33.             else if((obj1 != null) && (obj2 == null))
  34.             {
  35.                 return 1;
  36.             }
  37.             else if ((obj1 == null) && (obj2 != null))
  38.             {
  39.                 return -1;
  40.             }
  41.             
  42.             if (sortKind == Obj2SortKind.Code)
  43.             {
  44.                 if (obj1.Code > obj2.Code)
  45.                 {
  46.                     res = 1;
  47.                 }
  48.                 else if (obj1.Code < obj2.Code)
  49.                 {
  50.                     res = -1;
  51.                 }
  52.             }
  53.             else if(sortKind == Obj2SortKind.Name)
  54.             {
  55.                 res = obj1.Name.CompareTo(obj2.Name);
  56.             }
  57.             return res;
  58.         }
  59.         #endregion
  60.     }
  61. }

   第三种方法需要编写一个对象排序比较的方法,对List中的元素对象没有特殊的要求,但在比较方法中需要实现对象比较规则,这个方法实现后,就可以把这方名字作为参数委托给List的Sort方法,Sort方法在排序时会执行这个方法对List中的对象进行比较,详细可参照下面的代码。对List中元素我们还使用上面的SortTestObj2类对象。

  1.         static void Main(string[] args)
  2.         {
  3.             //利用代理方法进行排序
  4.             DelegateSort();
  5.         }
  6.         
  7.         //Sort(Comparison<(Of <(T>)>))方法排序,这中方法需要先编写一个对象比较的方法,然后
  8.         //把这个比较方法委托给List的Sort方法。
  9.         //对象比较的方法
  10.         private static int SortTestObj2Compare(SortTestObj2 obj1, SortTestObj2 obj2)
  11.         {
  12.             int res = 0;
  13.             if ((obj1 == null) && (obj2 == null))
  14.             {
  15.                 return 0;
  16.             }
  17.             else if ((obj1 != null) && (obj2 == null))
  18.             {
  19.                 return 1;
  20.             }
  21.             else if ((obj1 == null) && (obj2 != null))
  22.             {
  23.                 return -1;
  24.             }
  25.             if (obj1.Code > obj2.Code)
  26.             {
  27.                 res = 1;
  28.             }
  29.             else if (obj1.Code < obj2.Code)
  30.             {
  31.                 res = -1;
  32.             }
  33.             return res;
  34.         }
  35.         //List的委托排序
  36.         private static void DelegateSort()
  37.         {
  38.             List<SortTestObj2> objLst = new List<SortTestObj2>();
  39.             SortTestObj2 obj1 = new SortTestObj2();
  40.             obj1.Code = 3;
  41.             obj1.Name = "TestObj1";
  42.             objLst.Add(obj1);
  43.             SortTestObj2 obj2 = new SortTestObj2();
  44.             obj2.Code = 2;
  45.             obj2.Name = "TestObj2";
  46.             objLst.Add(obj2);
  47.             SortTestObj2 obj3 = new SortTestObj2();
  48.             obj3.Code = 4;
  49.             obj3.Name = "TestObj4";
  50.             objLst.Add(obj3);
  51.             SortTestObj2 obj4 = new SortTestObj2();
  52.             obj4.Code = 1;
  53.             obj4.Name = "TestObj3";
  54.             objLst.Add(obj4);
  55.             SortTestObj2 obj5 = new SortTestObj2();
  56.             obj5.Code = 6;
  57.             obj5.Name = "TestObj6";
  58.             objLst.Add(obj5);
  59.             objLst.Sort(SortTestObj2Compare);
  60.             Console.WriteLine("委托方法排序的结果");
  61.             foreach (SortTestObj2 item in objLst)
  62.             {
  63.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  64.             }
  65.         }

   对于第四排序方法,实际是第二种比较器排序的一个扩展,在指定排序比较器的同时,指定排序范围,即List中准备排序的开始元素索引和结束元素索引,代码样式如下:

  1. //按Name进行排序
  2.             SortTestObj2Camparer nameCmp = new SortTestObj2Camparer(Obj2SortKind.Name);
  3.             objLst.Sort(1, 3, nameCmp);

下面的代码是对上面介绍的四种方法的进行测试的代码,可以结合上面代码建立一个控制台工程体会一下。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Comparer.SortObject;
  5. using Comparer.Camparer;
  6. namespace Comparer
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             //List中的对象实现了IComparable接口时的排序
  13.             LstSort();
  14.             //利用比较器排序
  15.             LstComparerSort();
  16.             //利用比较器,对List中指定的区间的元素排序
  17.             LstFromToSort();
  18.             //利用代理方法进行排序
  19.             DelegateSort();
  20.         }
  21.         //Sort()方法排序
  22.         private static void LstSort()
  23.         {
  24.             List<SortTestObj1> objLst = new List<SortTestObj1>();
  25.             SortTestObj1 obj1 = new SortTestObj1();
  26.             obj1.Code = 3;
  27.             obj1.Name = "TestObj3";
  28.             objLst.Add(obj1);
  29.             SortTestObj1 obj2 = new SortTestObj1();
  30.             obj2.Code = 2;
  31.             obj2.Name = "TestObj2";
  32.             objLst.Add(obj2);
  33.             SortTestObj1 obj3 = new SortTestObj1();
  34.             obj3.Code = 4;
  35.             obj3.Name = "TestObj4";
  36.             objLst.Add(obj3);
  37.             //排序
  38.             objLst.Sort();
  39.             foreach(SortTestObj1 item in objLst)
  40.             {
  41.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  42.             }
  43.         }
  44.         //Sort(IComparer(T))方法排序
  45.         private static void LstComparerSort()
  46.         {
  47.             List<SortTestObj2> objLst = new List<SortTestObj2>();
  48.             SortTestObj2 obj1 = new SortTestObj2();
  49.             obj1.Code = 3;
  50.             obj1.Name = "TestObj1";
  51.             objLst.Add(obj1);
  52.             SortTestObj2 obj2 = new SortTestObj2();
  53.             obj2.Code = 2;
  54.             obj2.Name = "TestObj2";
  55.             objLst.Add(obj2);
  56.             SortTestObj2 obj3 = new SortTestObj2();
  57.             obj3.Code = 4;
  58.             obj3.Name = "TestObj4";
  59.             objLst.Add(obj3);
  60.             //按Code进行排序
  61.             SortTestObj2Camparer codeCmp = new SortTestObj2Camparer(Obj2SortKind.Code);
  62.             //排序
  63.             objLst.Sort(codeCmp);
  64.             Console.WriteLine("按Code排序的结果");
  65.             foreach (SortTestObj2 item in objLst)
  66.             {
  67.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  68.             }
  69.             //按Name进行排序
  70.             SortTestObj2Camparer nameCmp = new SortTestObj2Camparer(Obj2SortKind.Name);
  71.             objLst.Sort(nameCmp);
  72.             Console.WriteLine("按Name排序的结果");
  73.             foreach (SortTestObj2 item in objLst)
  74.             {
  75.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  76.             }
  77.         }
  78.         //Sort(Int32, Int32 IComparer(T))排序,指定List中排序的开始元素和终了元素
  79.         private static void LstFromToSort()
  80.         {
  81.             List<SortTestObj2> objLst = new List<SortTestObj2>();
  82.             SortTestObj2 obj1 = new SortTestObj2();
  83.             obj1.Code = 3;
  84.             obj1.Name = "TestObj1";
  85.             objLst.Add(obj1);
  86.             SortTestObj2 obj2 = new SortTestObj2();
  87.             obj2.Code = 2;
  88.             obj2.Name = "TestObj2";
  89.             objLst.Add(obj2);
  90.             SortTestObj2 obj3 = new SortTestObj2();
  91.             obj3.Code = 4;
  92.             obj3.Name = "TestObj4";
  93.             objLst.Add(obj3);
  94.             SortTestObj2 obj4 = new SortTestObj2();
  95.             obj4.Code = 1;
  96.             obj4.Name = "TestObj3";
  97.             objLst.Add(obj4);
  98.             SortTestObj2 obj5 = new SortTestObj2();
  99.             obj5.Code = 6;
  100.             obj5.Name = "TestObj6";
  101.             objLst.Add(obj5);
  102.             //按Code进行排序
  103.             SortTestObj2Camparer codeCmp = new SortTestObj2Camparer(Obj2SortKind.Code);
  104.             //排序
  105.             objLst.Sort(1, 3, codeCmp);
  106.             Console.WriteLine("按Code排序的结果");
  107.             foreach (SortTestObj2 item in objLst)
  108.             {
  109.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  110.             }
  111.             //按Name进行排序
  112.             SortTestObj2Camparer nameCmp = new SortTestObj2Camparer(Obj2SortKind.Name);
  113.             objLst.Sort(1, 3, nameCmp);
  114.             Console.WriteLine("按Name排序的结果");
  115.             foreach (SortTestObj2 item in objLst)
  116.             {
  117.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  118.             }
  119.         }
  120.         //Sort(Comparison<(Of <(T>)>))方法排序,这中方法需要先编写一个对象比较的方法,然后
  121.         //把这个比较方法委托给List的Sort方法。
  122.         //对象比较的方法
  123.         private static int SortTestObj2Compare(SortTestObj2 obj1, SortTestObj2 obj2)
  124.         {
  125.             int res = 0;
  126.             if ((obj1 == null) && (obj2 == null))
  127.             {
  128.                 return 0;
  129.             }
  130.             else if ((obj1 != null) && (obj2 == null))
  131.             {
  132.                 return 1;
  133.             }
  134.             else if ((obj1 == null) && (obj2 != null))
  135.             {
  136.                 return -1;
  137.             }
  138.             if (obj1.Code > obj2.Code)
  139.             {
  140.                 res = 1;
  141.             }
  142.             else if (obj1.Code < obj2.Code)
  143.             {
  144.                 res = -1;
  145.             }
  146.             return res;
  147.         }
  148.         //List的委托排序
  149.         private static void DelegateSort()
  150.         {
  151.             List<SortTestObj2> objLst = new List<SortTestObj2>();
  152.             SortTestObj2 obj1 = new SortTestObj2();
  153.             obj1.Code = 3;
  154.             obj1.Name = "TestObj1";
  155.             objLst.Add(obj1);
  156.             SortTestObj2 obj2 = new SortTestObj2();
  157.             obj2.Code = 2;
  158.             obj2.Name = "TestObj2";
  159.             objLst.Add(obj2);
  160.             SortTestObj2 obj3 = new SortTestObj2();
  161.             obj3.Code = 4;
  162.             obj3.Name = "TestObj4";
  163.             objLst.Add(obj3);
  164.             SortTestObj2 obj4 = new SortTestObj2();
  165.             obj4.Code = 1;
  166.             obj4.Name = "TestObj3";
  167.             objLst.Add(obj4);
  168.             SortTestObj2 obj5 = new SortTestObj2();
  169.             obj5.Code = 6;
  170.             obj5.Name = "TestObj6";
  171.             objLst.Add(obj5);
  172.             objLst.Sort(SortTestObj2Compare);
  173.             Console.WriteLine("委托方法排序的结果");
  174.             foreach (SortTestObj2 item in objLst)
  175.             {
  176.                 Console.WriteLine("Code=" + item.Code + ",Name=" + item.Name);
  177.             }
  178.         }
  179.     }
  180. }


posted @ 2011-08-23 20:42  有一  阅读(13886)  评论(0编辑  收藏  举报