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
知乎: @张赐荣
赐荣博客: www.prc.cx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!