发生了什么
您需要一个IComparer<T> 的实例才能在其上调用Compare 方法...记住这是一个接口,它没有静态方法。
这就是为什么这不起作用:
IComparer<T>.Compare(start.data, dat) > 0
另一方面,Comparer<T> 是一个类,它为您提供了一个静态属性 Default,它为您提供了一个 IComparer<T> 的实例...
这就是它起作用的原因:
Comparer<T>.Default.Compare(q.next.data, dat) < 0
获取IComparer<T> 的实例
您可以考虑使用 IComparer<T> 的实例存储一个字段,然后改用它。这将最大限度地减少混淆,并允许您在构造函数中获得一个 IComparer<T> 以存储在该字段中 - 这在客户想要自定义行为的情况下很有用。
默认实例
如果你想使用默认的比较器,你可以从中获取:
var comparer = Comparer<T>.Default;
此比较器将为您使用的任何T 提供默认行为。此行为等效于在 T 的实例上调用 CompareTo,并对空值进行额外处理。由于当您的实例为 null 时无法使用方法 CompareTo,您可能需要在调用 CompareTo 之前检查 null ...使用比较器消除了问题。
实现IComparer<T>
由于IComparer<T> 是一个接口,您可以编写一个类来实现它,该类必须有一个Compare 方法,具有您想要的任何逻辑。然后创建该类的一个实例,并在系统需要IComparer<T> 的地方使用它。
See the an example of implementing IComparer<T> on MSDN
// This class is not demonstrated in the Main method
// and is provided only to show how to implement
// the interface. It is recommended to derive
// from Comparer<T> instead of implementing IComparer<T>.
public class BoxComp : IComparer<Box>
{
// Compares by Height, Length, and Width.
public int Compare(Box x, Box y)
{
if (x.Height.CompareTo(y.Height) != 0)
{
return x.Height.CompareTo(y.Height);
}
else if (x.Length.CompareTo(y.Length) != 0)
{
return x.Length.CompareTo(y.Length);
}
else if (x.Width.CompareTo(y.Width) != 0)
{
return x.Width.CompareTo(y.Width);
}
else
{
return 0;
}
}
}
您的比较器将是该类的一个实例:
var comparer = new BoxComp();
注意:文档实际上建议从Comparer<T>继承而不是直接实现IComparer<T>,实用的原因是Comparer<T>除了IComparer<T>之外还实现了IComparer。
使用委托创建 IComparer<T>
如果您不熟悉委托是什么,假设它是对方法的引用,因此您可以拥有一个对方法的引用并传递它的变量。
你可以创建一个IComparer<T>,如果你有一个委托给一个进行比较的方法......这是通过调用方法Comparer<T>.Create来完成的,女巫将一个委托给你想要的方法。例如,您可以按如下方式使用 lambda 表达式:
var comparer = Comparer<string>.Create
(
(str1, str2) => str1.Length.CompareTo(str2.Length)
);
上面的代码是这个的简写:
Comparison<string> comparison = (str1, str2) => str1.Length.CompareTo(str2.Length);
var comparer = Comparer<string>.Create(comparison);
这又是这个的简写:
Comparison<string> comparison = delegate(string str1, string str2)
{
return str1.Length.CompareTo(str2.Length);
};
var comparer = Comparer<string>.Create(comparison);
对于这样的事情,什么是糖(除了在上面的代码中该方法是匿名的):
Comparison<string> comparison = StringComparison;
var comparer = Comparer<string>.Create(comparison);
// ...
private static int StringComparison(string str1, string str2)
{
return str1.Length.CompareTo(str2.Length);
}
额外读数: