我可以在整数上使用coalesce运算符来链接CompareTo吗?

时间:2011-10-24 20:06:37

标签: c# coalesce

我想做这样的事情:

public override int CompareTo (Foo rhs)
{
    return Bar.CompareTo(rhs.Bar) ??
           Baz.CompareTo(rhs.Baz) ??
           Fuz.CompareTo(rhs.Fuz) ?? 0;
}

这不像书面那样有效;是否有一些最小的解决方法使它工作?基本上我希望0链到非零(或链的末尾)。

5 个答案:

答案 0 :(得分:2)

基本没有,但是如果它确实会很好(IIRC,Jon在深度中提到了类似的C#想法)。您可以链接条件,但我倾向于使用:

int delta = Bar.CompareTo(rhs.Bar);
if(delta == 0) delta = Baz.CompareTo(rhs.Baz);
if(delta == 0) delta = Fuz.CompareTo(rhs.Fuz);
return delta;

答案 1 :(得分:2)

不是,??仅适用于空值(引用类型或可为空的结构)

int i;

i = Bar.CompareTo(rhs.Bar);
if (i != 0) return i;

i = Baz.CompareTo(rhs.Baz);
if (i != 0) return i;

i = Fuz.CompareTo(rhs.Fuz);
if (i != 0) return i;

return 0;

答案 2 :(得分:2)

语言不支持。但你可以这样写一个小帮手:

public override int CompareTo (Foo rhs)
{
    return FirstNonZeroValue(
        () => Bar.CompareTo(rhs.Bar), 
        () => Baz.CompareTo(rhs.Baz),
        () => Fuz.CompareTo(rhs.Fuz));
}

private int FirstNonZeroValue(params Func<int>[] comparisons)
{
    return comparisons.Select(x => x()).FirstOrDefault(x => x != 0);
}

答案 3 :(得分:0)

如果不需要短路,可以进行二进制算术运算。 It is not required that the Compare results must be -1, 0, or 1, but that they must be < 0, = 0, > 0。因此,通过使用2 ^ n作为系数,其中n是优先级,您可以总结CompareTo结果并根据需要获得数字> 0或<0。

所以,使用

return 4 * Bar.CompareTo(rhs.Bar)
     + 2 * Baz.CompareTo(rhs.Baz)
     + 1 * Fuz.CompareTo(rhs.Fuz);

答案 4 :(得分:0)

您还可以使用函数将零更改为null,并在没有Func<>的情况下获得惰性评估:

public override int CompareTo (Foo rhs) =>
    Bar.CompareTo(rhs.Bar).GetNullIfZero() ??
    Baz.CompareTo(rhs.Baz).GetNullIfZero() ??
    Fuz.CompareTo(rhs.Fuz);

public static class IntExtensions
{
    public static int? GetNullIfZero(this int i) => i == 0 ? null : (int?)i;
}

对于具有GetNullIfEmptyGetNullIfWhiteSpace扩展名的延迟链接字符串操作,有一种类似的方法。