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. if (sortKind == Obj2SortKind.Code)
  42. {
  43. if (obj1.Code > obj2.Code)
  44. {
  45. res = 1;
  46. }
  47. else if (obj1.Code < obj2.Code)
  48. {
  49. res = -1;
  50. }
  51. }
  52. else if(sortKind == Obj2SortKind.Name)
  53. {
  54. res = obj1.Name.CompareTo(obj2.Name);
  55. }
  56. return res;
  57. }
  58. #endregion
  59. }
  60. }

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

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

对于第四排序方法,实际是第二种比较器排序的一个扩展,在指定排序比较器的同时,指定排序范围,即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. }