[譯]在C#中使用IComparable和IComparer接口
原文:Use the IComparable and IComparer interfaces in Visual CSharp
本文介紹了在Visual C#中如何使用IComparer和IComparable接口。
概要
本文同時(shí)討論了IComparable和IComparer接口,原因有兩點(diǎn)。這兩個(gè)接口經(jīng)常一起使用。雖然接口類似且名稱相似,但它們卻有不同的用途。
如果你有一個(gè)支持IComparer的類型數(shù)組(例如字符串或整數(shù)),你可以對(duì)它進(jìn)行排序而不需要提供任何對(duì)IComparer的顯式引用(譯注:意思是把一個(gè)IComparer的實(shí)現(xiàn)類作為參數(shù)傳遞給排序方法)。在這種情況下,數(shù)組元素會(huì)被轉(zhuǎn)換為IComparer的默認(rèn)實(shí)現(xiàn)(Comparer.Default)。然而,如果你想為自定義對(duì)象提供排序或比較能力,你必須實(shí)現(xiàn)這兩個(gè)接口中的一個(gè)或兩個(gè)。
本文引用了Microsoft .NET Framework類庫(kù)命名空間System.Collections。
IComparable 接口
IComparable 接口的作用是提供一種比較特定類型的兩個(gè)對(duì)象的方法。如果你想為你的對(duì)象提供任何排序能力,那么這是必須的。可以將 IComparable 視為為你的對(duì)象提供默認(rèn)的排序順序。例如,如果你有一個(gè)對(duì)象類型的數(shù)組,然后你在該數(shù)組上調(diào)用 Sort 方法,則排序期間的對(duì)象比較是由 IComparable 提供的。當(dāng)你實(shí)現(xiàn) IComparable 接口時(shí),必須實(shí)現(xiàn) CompareTo 方法,如下所示:
// IComparable 的 CompareTo 方法,提供默認(rèn)的排序。 int IComparable.CompareTo(object obj) { Car c=(Car)obj; return String.Compare(this.make,c.make); }
CompareTo 方法中如何進(jìn)行比較取決于被比較值的數(shù)據(jù)類型。在本例中使用 String.Compare方法,因?yàn)楸贿x擇用于比較的屬性是字符串。
IComparer 接口
IComparer 接口的作用是提供更多的比較機(jī)制。例如,你可能想要你的類的排序上使用多個(gè)字段或?qū)傩裕谕蛔侄紊咸峁┥蚝徒敌颍蛘邇烧呒娑兄#ㄗg注,這個(gè)時(shí)候就必須要使用IComparer 接口了。)
使用 IComparer 是一個(gè)兩步過(guò)程。首先,聲明一個(gè)實(shí)現(xiàn) IComparer 的類,然后實(shí)現(xiàn) Compare 方法:
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 方法需要三元比較。根據(jù)其中一個(gè)值是否大于、等于或小于另一個(gè)值,返回1、0或-1。可以通過(guò)切換此方法中的邏輯運(yùn)算符來(lái)更改排序順序(升序或降序)。
第二步是聲明一個(gè)返回IComparer對(duì)象實(shí)例的方法:
public static IComparer SortYearAscending() { return (IComparer) new SortYearAscendingHelper(); }
在本例中,該對(duì)象被用作第二個(gè)參數(shù)被傳遞給Array.Sort的接受IComparer實(shí)例的重載方法。IComparer的使用并不局限于數(shù)組。它被許多不同的集合和控件類接受為參數(shù)。
逐步講解的示例:
以下示例演示了如何使用這些接口。為了演示IComparer和IComparable,我們創(chuàng)建了一個(gè)名為Car的類,該類擁有Make和Year兩個(gè)屬性。通過(guò)IComparable接口,為Make字段啟用了升序排序;通過(guò)IComparer接口,為Make字段啟用了降序排序。通過(guò)使用IComparer,為Year屬性提供了升序和降序排序。
1. 在Visual Studio中創(chuàng)建一個(gè)新的Console Application項(xiàng)目,把它命名為ConsoleEnum。
2. 將Program.cs重命名為Host.cs,然后用以下代碼替換原有代碼。
1 using System; 2 3 namespace ConsoleEnum 4 { 5 class host 6 { 7 [STAThread] 8 static void Main(string[] args) 9 { 10 // Create an array of Car objects. 11 Car[] arrayOfCars= new Car[6] 12 { 13 new Car("Ford",1992), 14 new Car("Fiat",1988), 15 new Car("Buick",1932), 16 new Car("Ford",1932), 17 new Car("Dodge",1999), 18 new Car("Honda",1977) 19 }; 20 21 // Write out a header for the output. 22 Console.WriteLine("Array - Unsorted\n"); 23 24 foreach(Car c in arrayOfCars) 25 Console.WriteLine(c.Make + "\t\t" + c.Year); 26 27 // Demo IComparable by sorting array with "default" sort order. 28 Array.Sort(arrayOfCars); 29 Console.WriteLine("\nArray - Sorted by Make (Ascending - IComparable)\n"); 30 31 foreach(Car c in arrayOfCars) 32 Console.WriteLine(c.Make + "\t\t" + c.Year); 33 34 // Demo ascending sort of numeric value with IComparer. 35 Array.Sort(arrayOfCars,Car.SortYearAscending()); 36 Console.WriteLine("\nArray - Sorted by Year (Ascending - IComparer)\n"); 37 38 foreach(Car c in arrayOfCars) 39 Console.WriteLine(c.Make + "\t\t" + c.Year); 40 41 // Demo descending sort of string value with IComparer. 42 Array.Sort(arrayOfCars,Car.SortMakeDescending()); 43 Console.WriteLine("\nArray - Sorted by Make (Descending - IComparer)\n"); 44 45 foreach(Car c in arrayOfCars) 46 Console.WriteLine(c.Make + "\t\t" + c.Year); 47 48 // Demo descending sort of numeric value using IComparer. 49 Array.Sort(arrayOfCars,Car.SortYearDescending()); 50 Console.WriteLine("\nArray - Sorted by Year (Descending - IComparer)\n"); 51 52 foreach(Car c in arrayOfCars) 53 Console.WriteLine(c.Make + "\t\t" + c.Year); 54 55 Console.ReadLine(); 56 } 57 } 58 }
3. 在項(xiàng)目中新增一個(gè)類,命名為Car。
4. 用下面的代碼替換Car.cs中的代碼。
1 using System; 2 using System.Collections; 3 namespace ConsoleEnum 4 { 5 public class Car : IComparable 6 { 7 // Beginning of nested classes. 8 // Nested class to do ascending sort on year property. 9 private class SortYearAscendingHelper: IComparer 10 { 11 int IComparer.Compare(object a, object b) 12 { 13 Car c1=(Car)a; 14 Car c2=(Car)b; 15 16 if (c1.year > c2.year) 17 return 1; 18 19 if (c1.year < c2.year) 20 return -1; 21 22 else 23 return 0; 24 } 25 } 26 27 // Nested class to do descending sort on year property. 28 private class SortYearDescendingHelper: IComparer 29 { 30 int IComparer.Compare(object a, object b) 31 { 32 Car c1=(Car)a; 33 Car c2=(Car)b; 34 35 if (c1.year < c2.year) 36 return 1; 37 38 if (c1.year > c2.year) 39 return -1; 40 41 else 42 return 0; 43 } 44 } 45 46 // Nested class to do descending sort on make property. 47 private class SortMakeDescendingHelper: IComparer 48 { 49 int IComparer.Compare(object a, object b) 50 { 51 Car c1=(Car)a; 52 Car c2=(Car)b; 53 return String.Compare(c2.make,c1.make); 54 } 55 } 56 // End of nested classes. 57 private int year; 58 private string make; 59 60 public Car(string Make,int Year) 61 { 62 make=Make; 63 year=Year; 64 } 65 66 public int Year 67 { 68 get {return year;} 69 set {year=value;} 70 } 71 72 public string Make 73 { 74 get {return make;} 75 set {make=value;} 76 } 77 // Implement IComparable CompareTo to provide default sort order. 78 int IComparable.CompareTo(object obj) 79 { 80 Car c=(Car)obj; 81 return String.Compare(this.make,c.make); 82 } 83 // Method to return IComparer object for sort helper. 84 public static IComparer SortYearAscending() 85 { 86 return (IComparer) new SortYearAscendingHelper(); 87 } 88 // Method to return IComparer object for sort helper. 89 public static IComparer SortYearDescending() 90 { 91 return (IComparer) new SortYearDescendingHelper(); 92 } 93 // Method to return IComparer object for sort helper. 94 public static IComparer SortMakeDescending() 95 { 96 return (IComparer) new SortMakeDescendingHelper(); 97 } 98 99 } 100 }
5. 運(yùn)行項(xiàng)目。Console窗口顯示如下:
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

浙公網(wǎng)安備 33010602011771號(hào)