在泛型函数中使用重载运算符==

考虑下面的代码:

class CustomClass
{
    public CustomClass(string value)
        { m_value = value; }

    public static bool operator ==(CustomClass a, CustomClass b)
        { return a.m_value == b.m_value; }

    public static bool operator !=(CustomClass a, CustomClass b)
        { return a.m_value != b.m_value; }

    public override bool Equals(object o)
        { return m_value == (o as CustomClass).m_value; }

    public override int GetHashCode()
        { return 0; /* not needed */ }

    string m_value;
}

class G
{
    public static bool enericFunction1<T>(T a1, T a2) where T : class
        { return a1.Equals(a2); }
    public static bool enericFunction2<T>(T a1, T a2) where T : class
        { return a1==a2; }
}

现在当我调用两个泛型函数时,一个成功,一个失败:

var a = new CustomClass("same value");
var b = new CustomClass("same value");
Debug.Assert(G.enericFunction1(a, b)); // Succeeds
Debug.Assert(G.enericFunction2(a, b)); // Fails

显然,G.enericFunction2执行默认的operator ==实现,而不是我的覆盖。 有谁能解释为什么会发生这种情况?


来自类型参数的约束(C#编程指南):

在应用where T:class约束时,避免在类型参数上使用==和!=运算符,因为这些运算符只会测试参考身份,而不是为了值相等。 即使这些运算符在用作参数的类型中被重载,情况也是如此。 (...)这种行为的原因是,在编译时,编译器只知道T是引用类型,因此必须使用对所有引用类型都有效的默认运算符。


如果我将enericFunction2更改为:

    public static bool enericFunction2<T>(T a1, T a2) where T : class
    {
        object aa = a1;
        CustomClass obj1 = (CustomClass)aa;

        object bb = a2;
        CustomClass obj2 = (CustomClass)bb;

        return obj1 == obj2; 
    }

然后一切正常。 但我恐怕我无法解释它。 我的意思是a1a2知道他们的类型。 为什么需要对CustomClass ,因此调用操作符?

链接地址: http://www.djcxy.com/p/58615.html

上一篇: Using overloaded operator== in a generic function

下一篇: Why can't I compare a KeyValuePair<TKey, TValue> with default