C# 通過實現IComparer<t> 泛型介面比較物件
C#實現IComparer 泛型介面讓物件可比較
問題
您有一種資料型別,它將儲存為 List
解決辦法
例(1)演示瞭如何實現 IComparable
例 (1) :通過實現 IComparable
public class Square : IComparable<Square> { public Square() { } public Square(int height, int width) { this.Height = height; this.Width = width; } public int Height { get; set;} public int Width { get; set;} public int CompareTo(object obj) { Square square = obj as Square; if (square != null) return CompareTo(square); throw new ArgumentException( "被比較的兩個物件必須是Square型別。"); } public override string ToString()=> ($"Height: {this.Height} Width: {this.Width}"); public override bool Equals(object obj) { if (obj == null) return false; Square square = obj as Square; if(square != null) return this.Height == square.Height; return false; } public override int GetHashCode() { return this.Height.GetHashCode() | this.Width.GetHashCode(); } public static bool operator ==(Square x, Square y) => x.Equals(y); public static bool operator !=(Square x, Square y) => !(x == y); public static bool operator <(Square x, Square y) => (x.CompareTo(y) < 0); public static bool operator >(Square x, Square y) => (x.CompareTo(y) > 0); public int CompareTo(Square other) { long area1 = this.Height * this.Width; long area2 = other.Height * other.Width; if (area1 == area2) return 0; else if (area1 > area2) return 1; else if (area1 < area2) return -1; else return -1; } }
講解
通過在類(或結構)上實現 IComparable
當呼叫 List
IComparer
例 (2) :通過實現 IComparer 使型別可排序
public class CompareHeight : IComparer<Square>
{
public int Compare(object firstSquare, object secondSquare)
{
Square square1 = firstSquare as Square;
Square square2 = secondSquare as Square;
if (square1 == null || square2 == null) throw (new ArgumentException("兩個引數都必須是Square型別。")); else return Compare(firstSquare,secondSquare);
}
public int Compare(Square x, Square y)
{
if (x.Height == y.Height) return 0; else if (x.Height > y.Height) return 1; else if (x.Height < y.Height) return -1; else return -1;
}
}
然後將這個類傳入 Sort 方法的 IComparer 引數。現在您可以指定以不同的方式對 Square 物件進行排序。比較器中實現的比較方法必須保持一致並應用全域性排序,從而使得比較函式宣告兩個資料項相等時絕對正確,而不是以下情況的結果:一個數據項不大於另一個數據項或者一個數據項不小於另一個數據項。
為了獲得最佳效能,需要保持 CompareTo 方法短小、高效,因為它將被 Sort 方法呼叫多次。例如,在對含有 4 個數據項的陣列排序時,Compare 方法將被呼叫 10 次。
例 (3) 中展示的 TestSort 方法演示瞭如何對 List
例 (3) :TestSort 方法
public static void TestSort()
{
List<Square> listOfSquares = new List<Square>(){
new Square(1,3),
new Square(4,3),
new Square(2,1),
new Square(6,1)};
// Test a List<String>
Console.WriteLine("List<String>");
Console.WriteLine("Original list");
foreach (Square square in listOfSquares)
{
Console.WriteLine(square.ToString());
}
Console.WriteLine();
IComparer<Square> heightCompare = new CompareHeight();
listOfSquares.Sort(heightCompare);
Console.WriteLine("Sorted list using IComparer<Square>=heightCompare");
foreach (Square square in listOfSquares)
{
Console.WriteLine(square.ToString());
}
Console.WriteLine();
Console.WriteLine("Sorted list using IComparable<Square>");
listOfSquares.Sort();
foreach (Square square in listOfSquares)
{
Console.WriteLine(square.ToString());
}
// Test a SORTEDLIST
var sortedListOfSquares = new SortedList<int, Square>(){
{ 0, new Square(1,3)},
{ 2, new Square(3,3)},
{ 1, new Square(2,1)},
{ 3, new Square(6,1)}};
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("SortedList<Square>");
foreach (KeyValuePair<int, Square> kvp in sortedListOfSquares)
{
Console.WriteLine($"{kvp.Key} : {kvp.Value}");
}
}
這些程式碼的輸出如下所示。List<String> Original list Height:1 Width:3 Height:4 Width:3 Height:2 Width:1 Height:6 Width:1 Sorted list using IComparer<Square>=heightCompare Height:1 Width:3 Height:2 Width:1 Height:4 Width:3 Height:6 Width:1 Sorted list using IComparable<Square> Height:2 Width:1 Height:1 Width:3 Height:6 Width:1 Height:4 Width:3 SortedList<Square> 0 : Height:1 Width:3 1 : Height:2 Width:1 2 : Height:3 Width:3 3 : Height:6 Width:1
參考
- (1) 《IComparer
介面 (System.Collections.Generic)》: https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.icomparer-1