支持 IComparable 时比较的语法

Syntax for comparing when supporting IComparable

见下面的代码。 第一 > 第二下有一条红色波浪线 运算符不能应用于操作数 OBJ 和 OBJ。

是否有一些简单的方法可以实现此处的目的?

public static OBJ Swap<OBJ>(ref OBJ first, ref OBJ second) where OBJ : IComparable
{
    OBJ temp = first;
    OBJ temp2 = second;
    second = temp;
    first = temp2;
    if (first > second) return first else return second;
}
 if (first.CompareTo(second) > 0) return first else return second;

If (i > j) works because int supports IComparable.

没有。这是不正确的。它之所以有效,是因为它实现了 comparison operators。例如:

public static bool operator >(MyClass l, MyClass r) {
    return l.Value > r.Value;
}

这与 IComparable 无关,后者要求在实现 classes:

时定义单个 实例方法
public int CompareTo(object obj) {

完全有可能创建一个 class 实现 IComparable 而无需比较运算符,反之亦然。

你对 public static OBJ Swap<OBJ>(ref OBJ first, ref OBJ second) where OBJ : IComparable 所说的只是 OBJ 应该实现 IComparable - 没有任何暗示这里传递的类型将定义比较运算符。因此,编译器不允许您对可能未定义比较运算符的对象执行相等比较。

我知道您在想 "but the compiler can work out what I've passed at compile time",但请记住,您编译的应用程序(即使是 .exe 格式)可能会被外部应用程序引用,从而传递无效类型。

您应该改用 CompareTo:

return a.CompareTo(b) > 0 ? a : b;

你得到编译时错误的原因是你对类型的唯一限制是它实现 IComparable,接口保证的唯一方法是 CompareTo 方法,并非所有类型都实现比较运算符。

由于 CompareTo 保证可用,但是您可以使用它。

另请注意,在调用 CompareTo 方法时应使用空条件运算符 (?.),因为 first 可能是 null(在在这种情况下,调用 .CompareTo 将抛出 ArgumentNullException).

您的其余代码也可以稍微简化。首先,在决定将哪个项目 return 时,可以使用三元运算符 (?:) 稍微缩短它。其次,在交换操作中,您只需要一个 temp 变量来保存您重新分配的第一个变量的值。例如:

public static T Swap<T>(ref T first, ref T second) where T : IComparable
{
    var temp = first;
    first = second;
    second = temp;

    return first?.CompareTo(second) > 0 ? first : second;
}

这里是 null 值会抛出异常的情况,但上面的代码按预期工作:

string first = null;
string second = "2";

string largest = Swap(ref first, ref second);