支持 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);
见下面的代码。 第一 > 第二下有一条红色波浪线 运算符不能应用于操作数 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);