考虑下面的代码:在泛型函数重载使用运算符==
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执行默认的运算符==实现,而不是我的覆盖。有谁能解释为什么会发生这种情况?
说'a1.Equals(a2)'调用**虚拟**实例方法。即使重载是在编译时固定的(对于System.Object.Equals(System.Object)),在运行时它总是被重载的方法被调用。这就是虚拟方法的全部内容。说'a1 == a2'调用一个'static'方法(至少在形式上存在一个方法'public static bool operator ==(object x,object y){...}')。调用'=='的重载在编译时是固定的,并且由于'T'不受限于匹配自定义'=='的东西,编译器可以选择的唯一东西就是'object' version == '。 – 2013-01-05 19:04:34