泛型等于将输入参数和对象约束为具有相同类型T的方法

时间:2012-05-10 19:25:31

标签: c#

以下[c#]代码将无法编译,错误“operator ==不能应用于'T'和'T'类型的操作数”。

public class Widget<T> where T: IComparable
{
    public T value;
    public Widget(T input) { value = input; }
    public bool Equals<T>(Widget<T> w) where T : System.IComparable
    {
        return (w.value == value);
    }
}

有没有办法将w输入参数的类型T约束为与被比较的对象相同的类型T,从而保证它们可以相互比较并消除编译器错误?在下面的值前面使用(动态)允许它编译,但似乎有一种更好的方法可以在编译时捕获问题:

public bool Equals<T>(Widget<T> w) where T : System.IComparable { return (w.value == (dynamic) value); }

4 个答案:

答案 0 :(得分:3)

假设您真的真的对价值平等感兴趣,您可以使用EqualityComparer.Default

EqualityComparer<T> comparer = EqualityComparer<T>.Default;
return comparer.Equals(w.value, value);

请注意,目前您的Equals方法也是通用的,尝试声明另一个类型参数T.我不认为您真的想这样做。

答案 1 :(得分:0)

public class Widget<T> where T: IComparable
{
    public T value;
    public Widget(T input) { value = input; }
    public bool Equals(Widget<T> other)
    {
        if(value == null)
        {
          return other == null || other.Value == null;
        }
        if(other == null) return false; //ensure next line doesn't get null pointer exception
        return value.CompareTo(other.Value) == 0;
    }
}

您可能需要根据您希望它的行为方式使用空检查逻辑,其中valueotherother.value的各种排列为空。

答案 2 :(得分:0)

这是你想要的吗?

public class Widget<T> : IEquatable<Widget<T>>, IComparable<Widget<T>>
    where T : IEquatable<T>, IComparable<T>
{
    public T value;
    public Widget(T input) { value=input; }
    public override bool Equals(object obj)
    {
        if(obj is Widget<T>)
        {
            return Equals(obj as Widget<T>);
        }
        return false;
    }
    public override int GetHashCode()
    {
        return value.GetHashCode();
    }
    public bool Equals(Widget<T> other)
    {
        return value.Equals(other.value);
    }

    public int CompareTo(Widget<T> other)
    {
        return value.CompareTo(other.value);
    }
    public static bool operator==(Widget<T> a, Widget<T> b)
    {
        return a.Equals(b);
    }
    public static bool operator!=(Widget<T> a, Widget<T> b)
    {
        return !a.Equals(b);
    }
    public static bool operator<(Widget<T> a, Widget<T> b)
    {
        return a.CompareTo(b)==-1;
    }
    public static bool operator>(Widget<T> a, Widget<T> b)
    {
        return a.CompareTo(b)==1;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Widget<int> a=new Widget<int>(100);
        Widget<int> b=new Widget<int>(200);

        if(a==b||a>b)
        {
        }
    }
}

答案 3 :(得分:0)

public class Widget<T> where T: IEquatable<T>
{
    public T value;
    public Widget(T input) { value = input; }
    public bool Equals(Widget<T> w)
    {
        return (w.value.Equals(this.value));
    }
}

如果您需要相等比较,那么您应该使用IEquatableIComparable更适合您何时需要订单比较(小于,大于)。

我认为您的主要错误是您在Equals<T>方法中引入了新的类型参数。别;相反,让T参数中的Widget<T>与实例化该类的类型相同。这可以保证w.Valuethis.value的类型相同。