C# 痛苦的泛型,运算符'&燃气轮机=';无法应用于类型为';T';和';T';

C# 痛苦的泛型,运算符'&燃气轮机=';无法应用于类型为';T';和';T';,c#,generics,C#,Generics,这是我的密码: 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; ... } ...

这是我的密码:

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);
        }
     }
}
类二进制树
{
专用节点头;
公共类节点
{
公共数据;
公共节点权;
公共节点左;
公共节点父节点;
...
}
...
私有void插入(ref T数据、节点父节点、ref节点currentChild)
{
...
{
如果(currentChild.Data>=Data)插入(ref Data,currentChild,ref currentChild.right);
else插入(ref data,currentChild,ref currentChild.left);
}
}
}
如果(currentChild.Data>=Data)我得到错误:

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


如何解决该错误?

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

您需要指定T实现IComparable,以便可以比较:

class BinaryTree<T> where T : IComparable<T>
{
    ...
    public class node<T> where T : IComparable<T> ...
    ...
    if (currentChild.Data.CompareTo(data) >= 0) ...
    ...
}
类二进制树,其中T:IComparable
{
...
公共类节点,其中T:IComparable。。。
...
如果(currentChild.Data.CompareTo(Data)>=0)。。。
...
}

这个问题的经典解决方案是(1)使
T
,或(2)对类使用或函子

(一)

类二进制树,其中T:Comparable。。。
(二)

类二进制树{
专用节点头;
专用只读IComparer比较器;
公共二叉树(IComparer comparer){
this.comparer=比较器;
}
//...
}

T应该是实现IComparable的类型,然后使用其compareto to方法而不是>=。如果您仍然希望支持>=。

我猜数据属于
对象类型,因此不自动允许>=操作,则运算符重载是另一种选择。
您需要为T添加一个约束,以便它是i可比较的

class BinaryTree<T> where T : IComparable
类二进制树,其中T:IComparable

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

的实例,但我不想使用
currentChild.Data.CompareTo(Data)>=0的表示法,还有其他方法吗?请您解释一下,其中T:IComparable如何告诉编译器T实现了IComparable?@Mr.Anubis这是泛型类型T的一个条件:它告诉编译器无法创建
BinaryTree
,除非
T
实现了
IComparable
。那么,如果我用不实现(继承)
IComparable
的用户定义类型实例化T,它还会破坏策略吗?不是吗?@Mr.Anubis编译器将捕获它,而代码将无法编译。
class BinaryTree<T> {
    private node<T> Head;
    private readonly IComparer<T> comparer;
    public BinaryTree(IComparer<T> comparer) {
        this.comparer = comparer;
    }
    //...
}
class BinaryTree<T> where T : IComparable