翼度科技»论坛 编程开发 .net 查看内容

[译]在C#中使用IComparable和IComparer接口

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
原文:Use the IComparable and IComparer interfaces in Visual CSharp
本文介绍了在Visual C#中如何使用IComparer和IComparable接口。
概要
本文同时讨论了IComparable和IComparer接口,原因有两点。这两个接口经常一起使用。虽然接口类似且名称相似,但它们却有不同的用途。
如果你有一个支持IComparer的类型数组(例如字符串或整数),你可以对它进行排序而不需要提供任何对IComparer的显式引用(译注:意思是把一个IComparer的实现类作为参数传递给排序方法)。在这种情况下,数组元素会被转换为IComparer的默认实现(Comparer.Default)。然而,如果你想为自定义对象提供排序或比较能力,你必须实现这两个接口中的一个或两个。
本文引用了Microsoft .NET Framework类库命名空间System.Collections。


IComparable 接口
IComparable 接口的作用是提供一种比较特定类型的两个对象的方法。如果你想为你的对象提供任何排序能力,那么这是必须的。可以将 IComparable 视为为你的对象提供默认的排序顺序。例如,如果你有一个对象类型的数组,然后你在该数组上调用 Sort 方法,则排序期间的对象比较是由 IComparable 提供的。当你实现 IComparable 接口时,必须实现 CompareTo 方法,如下所示:
  1. // IComparable 的 CompareTo 方法,提供默认的排序。
  2. int IComparable.CompareTo(object obj)
  3. {
  4.    Car c=(Car)obj;
  5.    return String.Compare(this.make,c.make);
  6. }
复制代码
CompareTo 方法中如何进行比较取决于被比较值的数据类型。在本例中使用 String.Compare方法,因为被选择用于比较的属性是字符串。


IComparer 接口
IComparer 接口的作用是提供更多的比较机制。例如,你可能想要你的类的排序上使用多个字段或属性,在同一字段上提供升序和降序,或者两者兼而有之。(译注,这个时候就必须要使用IComparer 接口了。)
使用 IComparer 是一个两步过程。首先,声明一个实现 IComparer 的类,然后实现 Compare 方法:
  1. private class SortYearAscendingHelper : IComparer
  2. {
  3.    int IComparer.Compare(object a, object b)
  4.    {
  5.       Car c1=(Car)a;
  6.       Car c2=(Car)b;
  7.       if (c1.year > c2.year)
  8.          return 1;
  9.       if (c1.year < c2.year)
  10.          return -1;
  11.       else
  12.          return 0;
  13.    }
  14. }
复制代码
注意:
IComparer.Compare 方法需要三元比较。根据其中一个值是否大于、等于或小于另一个值,返回1、0或-1。可以通过切换此方法中的逻辑运算符来更改排序顺序(升序或降序)。
第二步是声明一个返回IComparer对象实例的方法:
  1. public static IComparer SortYearAscending()
  2. {
  3.    return (IComparer) new SortYearAscendingHelper();
  4. }
复制代码
在本例中,该对象被用作第二个参数被传递给Array.Sort的接受IComparer实例的重载方法。IComparer的使用并不局限于数组。它被许多不同的集合和控件类接受为参数。


逐步讲解的示例:
以下示例演示了如何使用这些接口。为了演示IComparer和IComparable,我们创建了一个名为Car的类,该类拥有Make和Year两个属性。通过IComparable接口,为Make字段启用了升序排序;通过IComparer接口,为Make字段启用了降序排序。通过使用IComparer,为Year属性提供了升序和降序排序。
1. 在Visual Studio中创建一个新的Console Application项目,把它命名为ConsoleEnum。
2. 将Program.cs重命名为Host.cs,然后用以下代码替换原有代码。
  1. 1 using System;
  2. 2
  3. 3 namespace ConsoleEnum
  4. 4 {
  5. 5     class host
  6. 6     {
  7. 7        [STAThread]
  8. 8        static void Main(string[] args)
  9. 9        {
  10. 10           // Create an array of Car objects.
  11. 11           Car[] arrayOfCars= new Car[6]
  12. 12           {
  13. 13              new Car("Ford",1992),
  14. 14              new Car("Fiat",1988),
  15. 15              new Car("Buick",1932),
  16. 16              new Car("Ford",1932),
  17. 17              new Car("Dodge",1999),
  18. 18              new Car("Honda",1977)
  19. 19           };
  20. 20
  21. 21           // Write out a header for the output.
  22. 22           Console.WriteLine("Array - Unsorted\n");
  23. 23
  24. 24           foreach(Car c in arrayOfCars)
  25. 25              Console.WriteLine(c.Make + "\t\t" + c.Year);
  26. 26
  27. 27           // Demo IComparable by sorting array with "default" sort order.
  28. 28           Array.Sort(arrayOfCars);
  29. 29           Console.WriteLine("\nArray - Sorted by Make (Ascending - IComparable)\n");
  30. 30
  31. 31           foreach(Car c in arrayOfCars)
  32. 32              Console.WriteLine(c.Make + "\t\t" + c.Year);
  33. 33
  34. 34           // Demo ascending sort of numeric value with IComparer.
  35. 35           Array.Sort(arrayOfCars,Car.SortYearAscending());
  36. 36           Console.WriteLine("\nArray - Sorted by Year (Ascending - IComparer)\n");
  37. 37
  38. 38           foreach(Car c in arrayOfCars)
  39. 39              Console.WriteLine(c.Make + "\t\t" + c.Year);
  40. 40
  41. 41           // Demo descending sort of string value with IComparer.
  42. 42           Array.Sort(arrayOfCars,Car.SortMakeDescending());
  43. 43           Console.WriteLine("\nArray - Sorted by Make (Descending - IComparer)\n");
  44. 44
  45. 45           foreach(Car c in arrayOfCars)
  46. 46              Console.WriteLine(c.Make + "\t\t" + c.Year);
  47. 47
  48. 48           // Demo descending sort of numeric value using IComparer.
  49. 49           Array.Sort(arrayOfCars,Car.SortYearDescending());
  50. 50           Console.WriteLine("\nArray - Sorted by Year (Descending - IComparer)\n");
  51. 51
  52. 52           foreach(Car c in arrayOfCars)
  53. 53              Console.WriteLine(c.Make + "\t\t" + c.Year);
  54. 54
  55. 55           Console.ReadLine();
  56. 56        }
  57. 57    }
  58. 58 }
复制代码
3. 在项目中新增一个类,命名为Car。
4. 用下面的代码替换Car.cs中的代码。
  1.   1 using System;
  2.   2 using System.Collections;
  3.   3 namespace ConsoleEnum
  4.   4 {
  5.   5    public class Car : IComparable
  6.   6    {
  7.   7       // Beginning of nested classes.
  8.   8       // Nested class to do ascending sort on year property.
  9.   9       private class SortYearAscendingHelper: IComparer
  10. 10       {
  11. 11          int IComparer.Compare(object a, object b)
  12. 12          {
  13. 13             Car c1=(Car)a;
  14. 14             Car c2=(Car)b;
  15. 15
  16. 16             if (c1.year > c2.year)
  17. 17                return 1;
  18. 18
  19. 19             if (c1.year < c2.year)
  20. 20                return -1;
  21. 21
  22. 22             else
  23. 23                return 0;
  24. 24          }
  25. 25       }
  26. 26
  27. 27       // Nested class to do descending sort on year property.
  28. 28       private class SortYearDescendingHelper: IComparer
  29. 29       {
  30. 30          int IComparer.Compare(object a, object b)
  31. 31          {
  32. 32             Car c1=(Car)a;
  33. 33             Car c2=(Car)b;
  34. 34
  35. 35             if (c1.year < c2.year)
  36. 36                return 1;
  37. 37
  38. 38             if (c1.year > c2.year)
  39. 39                return -1;
  40. 40
  41. 41             else
  42. 42                return 0;
  43. 43          }
  44. 44       }
  45. 45
  46. 46       // Nested class to do descending sort on make property.
  47. 47       private class SortMakeDescendingHelper: IComparer
  48. 48       {
  49. 49          int IComparer.Compare(object a, object b)
  50. 50          {
  51. 51             Car c1=(Car)a;
  52. 52             Car c2=(Car)b;
  53. 53              return String.Compare(c2.make,c1.make);
  54. 54          }
  55. 55       }
  56. 56       // End of nested classes.
  57. 57       private int year;
  58. 58       private string make;
  59. 59
  60. 60       public Car(string Make,int Year)
  61. 61       {
  62. 62          make=Make;
  63. 63          year=Year;
  64. 64       }
  65. 65
  66. 66       public int Year
  67. 67       {
  68. 68          get  {return year;}
  69. 69          set {year=value;}
  70. 70       }
  71. 71
  72. 72       public string Make
  73. 73       {
  74. 74          get {return make;}
  75. 75          set {make=value;}
  76. 76       }
  77. 77       // Implement IComparable CompareTo to provide default sort order.
  78. 78       int IComparable.CompareTo(object obj)
  79. 79       {
  80. 80          Car c=(Car)obj;
  81. 81          return String.Compare(this.make,c.make);
  82. 82       }
  83. 83       // Method to return IComparer object for sort helper.
  84. 84       public static IComparer SortYearAscending()
  85. 85       {
  86. 86          return (IComparer) new SortYearAscendingHelper();
  87. 87       }
  88. 88       // Method to return IComparer object for sort helper.
  89. 89       public static IComparer SortYearDescending()
  90. 90       {
  91. 91          return (IComparer) new SortYearDescendingHelper();
  92. 92       }
  93. 93       // Method to return IComparer object for sort helper.
  94. 94       public static IComparer SortMakeDescending()
  95. 95       {
  96. 96         return (IComparer) new SortMakeDescendingHelper();
  97. 97       }
  98. 98
  99. 99    }
  100. 100 }
复制代码
5. 运行项目。Console窗口显示如下:
  1. Array - Unsorted
  2. Ford 1992
  3. Fiat 1988
  4. Buick 1932
  5. Ford 1932
  6. Dodge 1999
  7. Honda 1977
  8. Array - Sorted by Make (Ascending - IComparable)
  9. Buick 1932
  10. Dodge 1999
  11. Fiat 1988
  12. Ford 1932
  13. Ford 1992
  14. Honda 1977
  15. Array - Sorted by Year (Ascending - IComparer)
  16. Ford 1932
  17. Buick 1932
  18. Honda 1977
  19. Fiat 1988
  20. Ford 1992
  21. Dodge 1999
  22. Array - Sorted by Make (Descending - IComparer)
  23. Honda 1977
  24. Ford 1932
  25. Ford 1992
  26. Fiat 1988
  27. Dodge 1999
  28. Buick 1932
  29. Array - Sorted by Year (Descending - IComparer)
  30. Dodge 1999
  31. Ford 1992
  32. Fiat 1988
  33. Honda 1977
  34. Buick 1932
  35. Ford 1932
复制代码
 

来源:https://www.cnblogs.com/wenhx/archive/2023/04/26/use-icomparable-icomparer.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具