请看以下代码:
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==实现而不是我的重载。有人能解释一下为什么会发生这种情况吗?
a1.Equals(a2)
调用一个虚拟实例方法。即使重载在编译时被固定为System.Object.Equals(System.Object)
,在运行时总是调用被覆盖的方法。这就是虚拟方法的全部意义。说a1 == a2
调用一个静态
方法(至少形式上存在一个方法public static bool operator ==(object x, object y) { ... }
)。==
的重载在编译时被固定,由于T
没有被限制为与您的自定义==
匹配的内容,因此编译器唯一可以选择的是object
版本的==
。 - Jeppe Stig Nielsen