我真的很讨厌与IComparer合作 - 直到今天,经过多年与.Net的合作,我仍然经常被那些1和-1混淆。
我可以以某种自解释名称以某种方式替换Compare结果值,而不必在每次Compare调用后将输出整数转换为其他内容吗?
我尝试定义这样的枚举:
public enum ComparerResult
{
ALessThanB = -1,
Equal = 0,
AGreaterThanB = 1
}
if(comparer.Compare(a, b) == ComparerResult.ALessThanB)
但是如果没有演员阵容,那当然不会编译。
这当然也适用于IComparable.CompareTo。
感谢您的想法
答案 0 :(得分:7)
我更喜欢这个表达少于:
if (comparer.Compare(a, b) < 0)
这是一个很好的助记符,因为你使用相同的运算符与零进行比较,就像在两个操作数之间进行比较一样。
正如Reddog在评论中提醒我的那样,接口的规范并不特别要求-1和1;它只需要消极和积极的结果。因此,您目前使用的逻辑并不能保证在所有情况下都能正常工作。
答案 1 :(得分:2)
如何创建常量?这样你就不必从枚举中强制转换。
public class CompareHelper
{
public const int ALessThanB = -1;
public const int Equal = 0;
public const int AGreaterThanB = 1;
}
答案 2 :(得分:2)
IComparable
和IComparer
上的扩展方法怎么样?
public static class IComparableExtension
{
public static ComparerResult NiceCompareTo(this IComparable a, IComparable b)
{
int result = a.CompareTo(b);
if (result > 0) return ComparerResult.ALessThanB;
if (result < 0) return ComparerResult.AGreaterThanB;
return ComparerResult.Equal;
}
}
public static class IComparerExtension
{
public static ComparerResult NiceCompare(this IComparer c, IComparable a, IComparable b)
{
int result = c.Compare(a, b);
if (result > 0) return ComparerResult.ALessThanB;
if (result < 0) return ComparerResult.AGreaterThanB;
return ComparerResult.Equal;
}
}
答案 3 :(得分:1)
使用常量很危险。 IComparer.Compare的documentation仅指定返回值如果x < y
应该“小于零”,如果x > y
则返回“大于零”。所以你不应该假设返回值是[-1,0,1]中的一个。
我建议改为在IComparer上创建一个为您完成工作的扩展方法。
static MyCompare(this IComparable self, object x, object y)
{
var result = self.Compare(x, y);
if(result < 0) return ComparerResult.ALessthanB;
if(result == 0) return ComparerResult.Equal;
return ComparerResult.AGreaterThanB;
}