对此的回答可能非常明显,但无论如何我都会弯腰问。
我正在写一个Range<T>
课程,在这个过程中意识到我需要一个比较器。所以,我写了一个通用比较器,自然地从Comparer<T>
得出:
public class Range<T> where T : IComparable
{
// Simplified here for brevity -- actually uses the comparer
public T Min { get; set; }
// Simplified here for brevity -- actually uses the comparer
public T Max { get; set; }
private class DefaultComparer : Comparer<T>
{
public override int Compare(T x, T y)
{
return x == null && y == null
? 0
: x == null
? -1
: y == null
? 1
: x.CompareTo(y);
}
}
}
现在,这一切都运行良好,直到您传递Nullable<T>
作为类型。例如:
public Range<DateTime?> DateSentFilter { get; set; }
这可怕地打破了,因为当然Nullable<T>
没有实现IComparable
。这让我想到:为什么不呢?
鉴于比较器一般是如何编写的,为什么不能呢?
对这些东西有深入了解的人有什么想法吗?是否存在禁止这样做的情景?
答案 0 :(得分:4)
嗯,提供给Nullable<T>
的泛型类型不需要自己实现IComparable
。
您自己提供了此条件:T : IComparable
,但T
中的Nullable<T>
不一定如此。我同意Nullable<T>
经常用于实现IComparable
的原始类型,但您可以在结构上使用它,并且它们不会实现IComparable
。
答案 1 :(得分:4)
这是来自source code:
的评论// Warning, don't put System.Runtime.Serialization.On*Serializ*Attribute
// on this class without first fixing ObjectClone::InvokeVtsCallbacks
// Also, because we have special type system support that says a a boxed Nullable<T>
// can be used where a boxed<T> is use, Nullable<T> can not implement any intefaces
// at all (since T may not). Do NOT add any interfaces to Nullable!
//
正如它所说,Nullable<T>
由于给定的原因无法实现任何接口。
现在,第二个问题是:如果可以的话,他们会实施IComparable
吗?不,Patrick已经说明了原因。不是每个T
实现IComparable
,它都没有意义。