如何比较泛型类型的值?
我把它简化为一个最小的样本:
public class Foo<T> where T : IComparable
{
private T _minimumValue = default(T);
public bool IsInRange(T value)
{
return (value >= _minimumValue); // <-- Error here
}
}
错误是:
运算符“>=”不能应用于“t”和“t”类型的操作数。
究竟是什么!? T
已经被约束为IComparable
,即使将其约束为值类型(where t:struct
),我们仍然不能应用任何运算符,
>
,>
,,
>
,或
!=
。 (我知道对于==
和!=
存在涉及equals()
的变通方法,但它对关系运算符没有帮助)。
所以,有两个问题:
IComparable
的泛型类型的值呢? 它不是在某种程度上破坏了泛型约束的全部目的吗?(我意识到已经有一些问题与这个看似简单的问题相关--但没有一个线程给出详尽的或可行的答案,所以在这里。)
IComparable
不会重载>=
运算符。 您应该使用
value.CompareTo(_minimumValue) >= 0
运算符重载问题
不幸的是,接口不能包含重载运算符。 尝试在编译器中键入以下内容:
public interface IInequalityComaparable<T>
{
bool operator >(T lhs, T rhs);
bool operator >=(T lhs, T rhs);
bool operator <(T lhs, T rhs);
bool operator <=(T lhs, T rhs);
}
我不知道他们为什么不允许这样做,但我猜这会使语言定义复杂化,而且用户很难正确地实现。
要么是这样,要么是设计师不喜欢这种滥用的可能性。 例如,假设对类MagicMRMeow
执行>=
比较。 甚至在类矩阵
上。 关于这两个值的结果意味着什么?; 尤其是在有歧义的时候?
官方的解决办法
由于上述接口不合法,我们有IComparable
接口来解决这个问题。 它不实现运算符,只公开一个方法,int CompareTo(T other);
请参阅http://msdn.microsoft.com/en-us/library/4d7sx9hd.aspx
int
结果实际上是三位或三进制(类似于boolean
,但有三种状态)。 下表解释了结果的含义:
Value Meaning
Less than zero This object is less than
the object specified by the CompareTo method.
Zero This object is equal to the method parameter.
Greater than zero This object is greater than the method parameter.
使用变通办法
为了执行value>=_minimumvalue
的等价物,您必须改为编写:
value.CompareTo(_minimumValue) >= 0
如果value
可以为null,则当前答案可能失败。 请使用类似以下内容:
Comparer<T>.Default.Compare(value, _minimumValue) >= 0