【问题标题】:Limiting generic types in C#在 C# 中限制泛型类型
【发布时间】:2011-10-16 22:25:03
【问题描述】:

我有一个通用类MyClass<T>,其中T应该是那些可以比较的类型。

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

【问题讨论】:

    标签: c# generics types


    【解决方案1】:

    您不能限制为运算符,但可以限制为接口。因此,打算使用>=, <=, == 已被淘汰,但您可以使用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。)

    【讨论】:

    • IComparable 没有 Equals 方法,那就是 IEquatable
    • @nathan,你是对的,但是Equals 默认情况下是对象上的虚拟方法,所以我没有在答案中提到接口。为了清楚起见,将更新。
    • 我这样做了,但现在我收到了错误 operator &lt; cannot not be applied to T and T。我必须实施 CompareTo() 吗?我在想编译器会根据类型弄清楚这是如何完成的。
    • @rohit89,如前所述,您不能使用这些运算符。你不能约束它们,编译器也不能保证它们是被定义的。您想使用 CompareTo 方法,该方法已可用于 int、string、double 等。如果您自己的类也使用泛型方法/类,则需要在您自己的类上实现该接口。
    • 好的,我这里有个问题。我正在尝试将与int 一起使用的类转换为通用类。有多个地方使用关系运算符进行比较。我该如何处理这些线?
    【解决方案2】:

    如果速度与使用建议的方法相关,则会给您带来巨大的性能损失。如果没有,所有建议的东西都可以正常工作。

    这是一个我必须经常解决的问题,因为 C# 中的原始数据类型没有这里其他人经常建议和要求的“数字”数据类型。

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

    【讨论】:

    • 您认为性能下降的原因是什么?我不太清楚你为什么在这里提到数字数据类型。您想要哪种数字类型?
    • 我最近做了很多测试,因为在我们的框架中我们需要一个非常灵活的类型系统。假设您有一个不同原始数据类型的通用数组。您将如何遍历数组?您将如何执行通用数组的比较。由于在泛型和泛型数据类型上定义了操作,您将如何对此数组进行数学运算。这是具有数字数据类型限制的原因之一。也许这是一个太少的文字来解释我的情况,但这里有很多线程表明问题。
    【解决方案3】:

    如果你想把它限制在可以比较的东西上,你可以这样做:

    public class MyClass<T> where T:IComparable
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-25
        • 2017-05-19
        • 1970-01-01
        • 1970-01-01
        • 2018-07-23
        • 2021-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多