使用 IComparable.Compare 而不使用幻数

发布于 2024-12-27 15:35:29 字数 864 浏览 0 评论 0原文

我真的很讨厌使用 IComparer - 直到今天,使用 .Net 多年后,我仍然经常对那些 1 和 -1 感到困惑。

我可以以某种方式替换比较结果值具有一些不言自明的名称,而不必在每个 比较调用?

我试图定义一个这样的枚举:

public enum ComparerResult
{
    ALessThanB = -1,
    Equal = 0,
    AGreaterThanB = 1
}

if(comparer.Compare(a, b) == ComparerResult.ALessThanB)

但是如果没有强制转换,这当然不会编译。

这当然也适用于 IComparable .CompareTo

感谢您的想法

I really hate working with IComparer - to this day, after years of working with .Net, I still get regularly confused by those 1s and -1s.

Can I somehow replace the Compare result values with some self-explanatory names without having to cast the output integers to something else after every Compare call?

I tried to define an enum like this:

public enum ComparerResult
{
    ALessThanB = -1,
    Equal = 0,
    AGreaterThanB = 1
}

if(comparer.Compare(a, b) == ComparerResult.ALessThanB)

But that of course won't compile without a cast.

This of course also applies to IComparable.CompareTo.

Thanks for your ideas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谁人与我共长歌 2025-01-03 15:35:29

我更喜欢用它来表达小于:

if (comparer.Compare(a, b) < 0)

这是一个很好的助记符,因为您使用相同的运算符来与零进行比较,就像在两个操作数之间进行比较一样。


正如 Reddog 在评论中提醒我的那样,接口规范并不特别要求 -1 和 1;它只需要消极和积极的结果。因此,您当前使用的逻辑不能保证在所有情况下都有效。

I prefer this to express less-than:

if (comparer.Compare(a, b) < 0)

This is a nice mnemonic because you use the same operator for comparison with zero as you would between the two operands.


As Reddog reminded me in the comments, the specification for the interfaces does not require -1 and 1 specifically; it only requires negative and positive results. As such, the logic you're currently using is not guaranteed to work in all cases.

我还不会笑 2025-01-03 15:35:29

只创建常量怎么样?这样你就不必从枚举进行转换。

public class CompareHelper
{
    public const int ALessThanB = -1;
    public const int Equal = 0;
    public const int AGreaterThanB = 1;
}

How about just creating constants? That way you won't have to cast from an enum.

public class CompareHelper
{
    public const int ALessThanB = -1;
    public const int Equal = 0;
    public const int AGreaterThanB = 1;
}
没有心的人 2025-01-03 15:35:29

IComparableIComparer 上的扩展方法怎么样?

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;
    }
}

What about an extension method on IComparable and 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;
    }
}
风和你 2025-01-03 15:35:29

使用常量是危险的。 IComparer.Compare 的文档仅指定如果 x 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;
}

Using constants is dangerous. The documentation for IComparer.Compare only specifies that the return value should be "less than zero" if x < y, or "greater than zero" if x > y. So you should not assume that the return value will be one of [-1, 0, 1].

What I would suggest instead is creating an extension method on IComparer that does the work for you.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文