C#中的比较:运算符'<'不能应用于'T'和'T'类型的操作数

时间:2009-08-20 18:29:17

标签: c# generics

我创建了 BinaryTreeNode<T> 类,然后为 Add(T data) 类创建 BinaryTree<T> 方法。

当我尝试比较对象的值时编译器说:

  

运营商'&lt;'不能应用于'T'和'T'类型的操作数。

示例:

  public void AddNode(T data) {
        BinaryTreeNode<T> node = new BinaryTreeNode<T>(data);
        BinaryTreeNode<T> temp = root;

        if (temp.Value < node.Value) // **PROBLEM HERE**
        ...

我正在使用VS08 Express Edition。

3 个答案:

答案 0 :(得分:8)

您应该添加一个约束,以便T必须实现IComparable<T>,然后使用:

public class BinaryTree<T> where T : IComparable<T>
{
    public void AddNode(T data)
    {
        BinaryTreeNode<T> node = new BinaryTreeNode<T>(data);
        BinaryTreeNode<T> temp = root;

        if (temp.Value.CompareTo(node.Value) < 0)
        ...

另一种方法是传入IComparer<T>并使用:

public class BinaryTree<T> where T : IComparable<T>
{
    private readonly IComparer<T> comparer;

    public BinaryTree(IComparer<T> comparer)
    {
        this.comparer = comparer;
        ...
    }

    public void AddNode(T data)
    {
        BinaryTreeNode<T> node = new BinaryTreeNode<T>(data);
        BinaryTreeNode<T> temp = root;

        if (comparer.Compare(temp.Value, node.Value) < 0)

这是最接近保证“&lt;”的operator - 重载运算符是静态的,并且没有办法约束类型参数来要求它。

答案 1 :(得分:1)

使用Generic Constraints来缩小T可以的类型。这样您就可以确保可以使用您的运营商进行比较。

目前T可能是任何对象。例如,如果你有一个Car对象,那么编译器如何知道如何说一辆Car是“小于”还是“大于”另一辆?这就是你需要约束的原因。

答案 2 :(得分:1)

Value的类型(int,string,char [],MyClass,YourClass等)不支持'&lt;'操作。这对于大多数非内在数字类型来说是正常的,即int,long,decimal等。

T需要实现IComparable类,以便可以将其与T类型的其他对象进行比较。

因此,函数声明必须对T:

强制执行约束
public class BinaryTree<T> where T : IComparable<T>
{
    public void AddNode(T data) 

你必须确保无论T是什么,它都必须实现IComparable。

public class MyData : IComparable<MyData>
{
    public int CompareTo(MyData other)
    {
         // return -1 if 'this' is smaller than other, 0 if equals, 1 otherwise
    }
}

在添加功能中,然后调用

if( temp.Value.CompareTo(node.Value) < 0 )