本分步指南描述如何使用两个接口: IComparer和IComparable。在同一篇文章中讨论这些接口有两个原因。经常在一起,使用这些接口和接口类似 (并且有相似的名称),尽管它们用于不同用途。
如果您有一个数组的类型 (如字符串或整数) 已经在支持IComparer,可以该数组进行排序而不提供对IComparer的任何显式引用。在这种情况下,数组中的元素强制转换为IComparer (Comparer.Default) 为您的默认实现。但是,如果您想要为您自定义的对象提供排序或比较功能,则必须实现一个或这两种接口。
在这篇文章中引用以下.NET Framework 类库命名空间:
IComparable
IComparable的角色是提供方法可以比较两个对象的特定类型。这是有必要的如果您想要提供的对象的任何排序功能。将IComparable视为提供您的对象的默认排序顺序。例如,如果具有您的类型的对象的数组,则调用该阵列上的排序方法IComparable排序过程提供的比较结果的对象。实现IComparable接口时,必须实现CompareTo方法中,按如下所述:
// Implement IComparable CompareTo method - provide default sort order. int IComparable.CompareTo(object obj) { car c=(car)obj; return String.Compare(this.make,c.make); }
在方法的比较是根据数据类型的值进行比较的不同。在此示例中使用String.Compare是因为选择用于比较的属性是一个字符串。
IComparer
IComparer的角色是提供其它比较机制。例如,您可以提供对多个字段或属性,您的类的排序升序和降序顺序对相同的字段,或者这两者。
使用IComparer是一个两步过程。首先,声明实现IComparer,一个类,然后实现比较方法:
private class sortYearAscendingHelper : IComparer { int IComparer.Compare(object a, object b) { car c1=(car)a; car c2=(car)b; if (c1.year > c2.year) return 1; if (c1.year < c2.year) return -1; else return 0; } }
请注意IComparer.Compare方法需要第三级进行比较。根据大于、 等于还是小于另一个值是否返回 1,0,则为-1。通过使用此方法切换逻辑运算符,可以更改排序顺序 (升序或降序)。
第二步是声明一个返回 IComparer 对象的实例的方法:
public static IComparer sortYearAscending() { return (IComparer) new sortYearAscendingHelper(); }
在此的示例为第二个参数时,调用重载的 Array.Sort 方法接受 IComparer 使用对象。IComparer 的使用并不限于数组。它将被接受作为许多不同的集合和控件类中的参数。
分步示例
下面的示例演示如何使用这些接口。为了演示 IComparer 和 IComparable,创建一个名为 汽车 的类。汽车 对象都有 使 和 年属性。升序排序将 使 该字段启用通过 IComparable 接口和按降序排序在 使 该字段启用通过 IComparer 界面。为通过IComparer 使用的 年份 属性提供了既升序和降序排序。
- 在 Visual C#,创建新的控制台应用程序项目。命名应用程序 ConsoleEnum。
- 重命名为 Host.cs,Program.cs 然后将代码替换下面的代码。
注意在 Visual Studio.net 2003 年重命名为 Host.cs Class1.csusing System; namespace ConsoleEnum { class host { [STAThread] static void Main(string[] args) { // Create an arary of car objects. car[] arrayOfCars= new car[6] { new car("Ford",1992), new car("Fiat",1988), new car("Buick",1932), new car("Ford",1932), new car("Dodge",1999), new car("Honda",1977) }; // Write out a header for the output. Console.WriteLine("Array - Unsorted "); foreach(car c in arrayOfCars) Console.WriteLine(c.Make + " " + c.Year); // Demo IComparable by sorting array with "default" sort order. Array.Sort(arrayOfCars); Console.WriteLine(" Array - Sorted by Make (Ascending - IComparable) "); foreach(car c in arrayOfCars) Console.WriteLine(c.Make + " " + c.Year); // Demo ascending sort of numeric value with IComparer. Array.Sort(arrayOfCars,car.sortYearAscending()); Console.WriteLine(" Array - Sorted by Year (Ascending - IComparer) "); foreach(car c in arrayOfCars) Console.WriteLine(c.Make + " " + c.Year); // Demo descending sort of string value with IComparer. Array.Sort(arrayOfCars,car.sortMakeDescending()); Console.WriteLine(" Array - Sorted by Make (Descending - IComparer) "); foreach(car c in arrayOfCars) Console.WriteLine(c.Make + " " + c.Year); // Demo descending sort of numeric value using IComparer. Array.Sort(arrayOfCars,car.sortYearDescending()); Console.WriteLine(" Array - Sorted by Year (Descending - IComparer) "); foreach(car c in arrayOfCars) Console.WriteLine(c.Make + " " + c.Year); Console.ReadLine(); } } }
- 将类添加到项目中。命名类 汽车。
- 用下列替换代码中 Car.cs:
using System; using System.Collections; namespace ConsoleEnum { public class car : IComparable { // Beginning of nested classes. // Nested class to do ascending sort on year property. private class sortYearAscendingHelper: IComparer { int IComparer.Compare(object a, object b) { car c1=(car)a; car c2=(car)b; if (c1.year > c2.year) return 1; if (c1.year < c2.year) return -1; else return 0; } } // Nested class to do descending sort on year property. private class sortYearDescendingHelper: IComparer { int IComparer.Compare(object a, object b) { car c1=(car)a; car c2=(car)b; if (c1.year < c2.year) return 1; if (c1.year > c2.year) return -1; else return 0; } } // Nested class to do descending sort on make property. private class sortMakeDescendingHelper: IComparer { int IComparer.Compare(object a, object b) { car c1=(car)a; car c2=(car)b; return String.Compare(c2.make,c1.make); } } // End of nested classes. private int year; private string make; public car(string Make,int Year) { make=Make; year=Year; } public int Year { get {return year;} set {year=value;} } public string Make { get {return make;} set {make=value;} } // Implement IComparable CompareTo to provide default sort order. int IComparable.CompareTo(object obj) { car c=(car)obj; return String.Compare(this.make,c.make); } // Method to return IComparer object for sort helper. public static IComparer sortYearAscending() { return (IComparer) new sortYearAscendingHelper(); } // Method to return IComparer object for sort helper. public static IComparer sortYearDescending() { return (IComparer) new sortYearDescendingHelper(); } // Method to return IComparer object for sort helper. public static IComparer sortMakeDescending() { return (IComparer) new sortMakeDescendingHelper(); } } }
- 运行该项目。 在控制台窗口中将显示以下输出:
Array - Unsorted Ford 1992 Fiat 1988 Buick 1932 Ford 1932 Dodge 1999 Honda 1977 Array - Sorted by Make (Ascending - IComparable) Buick 1932 Dodge 1999 Fiat 1988 Ford 1932 Ford 1992 Honda 1977 Array - Sorted by Year (Ascending - IComparer) Ford 1932 Buick 1932 Honda 1977 Fiat 1988 Ford 1992 Dodge 1999 Array - Sorted by Make (Descending - IComparer) Honda 1977 Ford 1932 Ford 1992 Fiat 1988 Dodge 1999 Buick 1932 Array - Sorted by Year (Descending - IComparer) Dodge 1999 Ford 1992 Fiat 1988 Honda 1977 Buick 1932 Ford 1932