限制C#中的泛型类型

9

我有一个通用类 MyClass<T>,其中T应该仅限于可比较的类型。

这意味着仅数字类型和定义了关系运算符方法的类。我该如何实现?

4个回答

11

你不能将约束限制在运算符上,但是可以将其限制在接口上。因此,想要使用 >=, <=, == 是不行的,但是你可以使用 CompareTo, Equals

where T : IComparable<T>

接口文档

该接口提供了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
    }
}
< p > Equals 是默认作为 object 上的虚方法提供的。如果您想使用除引用相等性以外的其他内容,则需要在自己的自定义类型上重写此方法。(强烈建议同时重写 GetHashCode )


IComparable 接口没有 Equals 方法,那就得用 IEquatable。 - nathan gonzalez
@nathan,你说得对,但是Equals默认是对象上的虚方法,所以我在答案中没有提到接口。为了更清晰,我会进行更新。 - Anthony Pegram
我这样做了,但现在我得到了错误信息 operator < cannot not be applied to T and T。我是否需要实现 CompareTo() 方法?我认为编译器应该能够根据类型自动解决这个问题。 - rohit89
1
@rohit89,正如所说,您不能使用那些运算符。您无法对它们进行约束,编译器也无法保证它们被定义。您需要使用CompareTo方法,该方法已经适用于int、string、double等类型。如果您的类也要使用通用方法/类,则需要自己实现接口。 - Anthony Pegram
好的,我这里有一个问题。我正在尝试将一个使用 int 的类转换为通用类。有多个地方使用了关系运算符进行比较。我该如何处理这些行? - rohit89
@rohit89,我会提供一个样例。 - Anthony Pegram

3
你可以使用 where 修饰符将泛型类型限制为仅实现 IComparable 接口的类。
public class MyClass<K> where K : IComparable
{
  ....
}

3
如果你想限制比较对象,可以进行以下操作: ```` 如果您想将它们限制为可比较的内容,则可以执行以下操作: ````
public class MyClass<T> where T:IComparable

-1
如果速度很重要,使用建议的方法将会导致性能大幅下降。如果不是,所有建议的事情都可以正常工作。
这是一个我经常需要解决的问题,因为C#中的原始数据类型没有像其他人经常建议和要求的“数字”数据类型。
也许下一个版本的C#会有它,但我怀疑...

你为什么认为性能会降低?我不太确定你为什么在这里提到数字数据类型。你想要哪种数字类型? - oleksii
最近我做了很多测试,因为在我们的框架中需要一个非常灵活的类型系统。假设你有一个不同原始数据类型的通用数组。你会如何遍历这个数组?你会如何比较一个通用数组?你会如何对这个数组进行数学运算,因为通用数据类型上定义了操作。这是有数值数据类型限制的原因之一。也许这些文字有点少,无法解释我的情况,但这里有很多帖子展示了这个问题。 - msedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接