2011-07-31 214 views
9

我有一个泛型类MyClass<T>其中T应该只有是那些可以比较的类型。限制C#中的泛型类型

这意味着只有数字类型和类已经定义了关系运算符的方法。我该怎么做呢 ?

回答

10

您不能限制为运算符,但可以限制为接口。因此,打算使用>=, <=, ==已不在,但您可以使用CompareTo, Equals

where T : IComparable<T> 

Interface documentation

此接口带来您CompareTo方法,该方法是用于关系排序有用(大于,小于,等)。原语和字符串已经实现了这一点,但你需要为你自己的自定义类型实现这个。你会使用这样

void SomeMethod<T>(T alpha, T beta) where T : IComparable<T> 
{ 
    if (alpha.CompareTo(beta) > 0) 
    { 
     // alpha is greater than beta, replaces alpha > beta 
    } 
    else if (alpha.CompareTo(beta) < 0) 
    { 
     // alpha is less than beta, replaces alpha < beta 
    } 
    else 
    { 
     // CompareTo returns 0, alpha equals beta 
    } 
} 

Equals你默认为上object虚方法。如果您希望使用除引用相等之外的其他内容,您希望在您自己的自定义类型上重写此方法。 (这也是强烈推荐同时重写GetHashCode

+0

了IComparable没有Equals方法,那IEquatable –

+0

@nathan,你是正确的,但'Equals'是一个虚拟的方法对象默认情况下,所以我没有在答案中提到接口。为了清晰起见,将进行更 –

+0

我这样做了,但现在我得到错误'运营商<不能不适用于T和T'。我必须实现CompareTo()吗?我在想,编译器会根据类型来弄清楚这是如何完成的。 – rohit89

3

您可以将泛型类型限制为仅使用where修饰符实现IComparable接口的类。

public class MyClass<K> where K : IComparable 
{ 
    .... 
} 
3

如果要限制它的东西,能比的,你可以做这样的事情:

public class MyClass<T> where T:IComparable 
-1

如果速度是相关的使用建议的方法会给你带来巨大的性能损失。如果没有,所有建议的事情都可以正常工作。

这是一个我经常遇到的问题,因为C#中的原始数据类型没有像其他人经常暗示和要求的“数字”数据类型。

也许C#的下一个版本将拥有它,但我怀疑...

+0

为什么你认为性能下降?我不太确定你为什么在这里提到数字数据类型。你想要哪种数字类型? – oleksii

+0

我最近做了很多测试,因为在我们的框架中,我们需要一个非常灵活的类型系统。假设你有一个不同的基本数据类型的通用数组。你将如何运行一个数组?你将如何执行一个通用数组的比较。你将如何在这个数组上进行数学运算,因为在泛型数据类型上定义了操作。这是产生数字数据类型限制的原因之一。也许这是一个有点太少的文字来解释我的情况,但是这里有很多线索显示这个问题。 – msedi