【问题标题】:Painful Generics, Operator '>=' cannot be applied to operands of type 'T' and 'T'痛苦的泛型,运算符“>=”不能应用于“T”和“T”类型的操作数
【发布时间】:2012-01-25 10:43:01
【问题描述】:

这是我的代码:

class BinaryTree<T> 
{
    private node<T> Head;
    public class node<T> 
    {
     public T Data;
     public node<T> right;
     public node<T> left;
     public node<T> parent;
    ...
    }
    ...
    private void insert(ref T data, node<T> parent, ref node<T> currentChild) 
    {
    ...
        {
            if (currentChild.Data >= data) insert(ref data, currentChild, ref currentChild.right);
            else insert(ref data, currentChild, ref currentChild.left);
        }
     }
}

if (currentChild.Data &gt;= data)以上点我收到错误:

运算符“>=”不能应用于“T”和“T”类型的操作数

我该怎么做才能解决这个错误?

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    您需要指定 T 实现 IComparable 以便您进行比较:

    class BinaryTree<T> where T : IComparable<T>
    {
        ...
        public class node<T> where T : IComparable<T> ...
        ...
        if (currentChild.Data.CompareTo(data) >= 0) ...
        ...
    }
    

    【讨论】:

    • 但我不想使用currentChild.Data.CompareTo(data) &gt;= 0 表示法,还有其他方法吗?
    【解决方案2】:

    这个问题的经典解决方案是 (1) 使 T IComparable&lt;T&gt;,或 (2) 对您的类使用 IComparer&lt;T&gt; 或仿函数。

    (1)

    class BinaryTree<T> where T : Comparable<T> ...
    

    (2)

    class BinaryTree<T> {
        private node<T> Head;
        private readonly IComparer<T> comparer;
        public BinaryTree(IComparer<T> comparer) {
            this.comparer = comparer;
        }
        //...
    }
    

    【讨论】:

    • 你能解释一下 where T : IComparable 如何告诉编译器 T 实现了 IComparable 吗?
    • @Mr.Anubis 这是泛型类型 T 的一个条件:它告诉编译器 BinaryTree&lt;T&gt; 不能 被创建,除非 T 实现 IComparable&lt;T&gt;
    • 那么,如果我使用未实现(继承)IComparable&lt;T&gt; 的用户定义类型实例化 T ,它仍然违反策略吗?不是吗?
    • @Mr.Anubis 编译器要捕获它,代码不会编译。
    【解决方案3】:

    我不了解 C#,但在 Java 中,您需要有一个通用 Comparator 类的实例,并使用您想要比较的类型进行参数化。这个泛型类提供了一个 compareTo() 函数,该函数将以允许比较两种类型的方式实现。

    【讨论】:

      【解决方案4】:

      T 应该是实现 IComparable 的类型,然后使用它的 compareto to 方法而不是 >=。如果您仍想支持 >=,则运算符重载是另一种选择。

      【讨论】:

        【解决方案5】:

        虽然有些人建议使用 IComparable,但我建议改用 IComparer&lt;T&gt;,它应该存储在树的某个字段中。您的树的构造函数之一应该接受IComparer&lt;T&gt;,它应该存储在您的字段中。另一个可能应该将IComparer&lt;T&gt; 字段设置为Comparer&lt;T&gt;.InvariantDefault()。因此,您的树的消费者将能够选择如何对树中的事物进行排序。请注意,如果在构造类时提供了IComparer&lt;T&gt;,则没有真正的理由让T 必须实现IComparable&lt;T&gt;。在没有指定比较方法的情况下构造树时强制执行 T 实现 IComparer&lt;T&gt; 的编译时要求可能会很好,但是如果不需要像 treeInstance = factoryClass.Create&lt;myType&gt;() 这样有点尴尬的语法,就没有办法做到这一点,这会创建一个treeClass&lt;myType&gt; 的实例。

        【讨论】:

          【解决方案6】:

          我猜 Data 的类型是 Object,因此不会自动允许 >= 操作。
          您需要为 T 添加一个约束,使其为 IComparable

          class BinaryTree<T> where T : IComparable
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-04-04
            • 1970-01-01
            • 1970-01-01
            • 2013-06-09
            • 2011-08-14
            • 1970-01-01
            • 2020-05-05
            • 2015-12-11
            相关资源
            最近更新 更多