开发者

Using overloaded operator== in a generic function

开发者 https://www.devze.com 2023-01-01 00:37 出处:网络
Consider the following code: class CustomClass { public CustomClass(string value) { m_value = value; } public static bool operator ==(CustomClass a, CustomClass b)

Consider the following code:

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开发者_StackOverflow 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; }
}

Now when I call both generic functions, one succeeds and one fails:

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

Apparently, G.enericFunction2 executes the default operator== implementation instead of my override. Can anybody explain why this happens?


From Constraints on Type Parameters (C# Programming Guide):

When applying the where T : class constraint, avoid the == and != operators on the type parameter because these operators will test for reference identity only, not for value equality. This is the case even if these operators are overloaded in a type that is used as an argument. (...) The reason for this behavior is that, at compile time, the compiler only knows that T is a reference type, and therefore must use the default operators that are valid for all reference types.


If I change the enericFunction2 to:

    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; 
    }

Then everything works fine. But I am afraid I can't explain it. I mean a1 and a2 know their type. Why a cast is needed to the CustomClass, so the operators are called?

0

精彩评论

暂无评论...
验证码 换一张
取 消