2011-01-28 46 views

回答

4

实际上,它既不。无论您的Equals方法的重写行为(如果您已覆盖该方法,那么执行IEquatable<T>时肯定应该具有该方法),默认情况下,==运算符将测试引用相等性。

也就是说,如果您的变量键入为object,但您想使用自己的自定义相等比较,请使用Equals(x, y)而不是x == y

这样,即使你已经实现IEquatable<T>,一定要仍然覆盖object.Equals,像这样:

class MyType : IEquatable<MyType> 
{ 
    public bool Equals(MyType other) 
    { 
     // Whatever you want. 
    } 

    public override bool Equals(object other) 
    { 
     // Presumably you check for null above. 
     return Equals(other as MyType); 
    } 
} 

虽然你肯定可以还超载==!=运营商为你的类型,如果你有这种类型的对象只是object变量,像这样:

object x = new MyType(); 
object y = new MyType(); 
Console.WriteLine(Equals(x, y)); 
Console.WriteLine(x == y); 

以上内容不会像您所期望的那样工作(如果您已超载==并期望使用),因为==重载必须在编译时解决;由于xy被键入为任意对象,因此C#编译器将选择object类型的==运算符,该运算符再次仅用于测试引用相等性。


更新:现在,你可以确保==运营商使用,如果你其中定义它更派生类型的变量类型的类。例如,给定以下类型:

class A 
{ 
    public static bool operator ==(A x, A y) { return true; } 
    public static bool operator !=(A x, A b) { return false; } 
} 

class B : A { } 

class AComparer<T> where T : A 
{ 
    public bool CompareEqual(T x, T y) { return x == y; } 
} 

AComparer<T>.CompareEqual上述方法将使用您的重载==运营商任何类型TA导出。

需要记住的重要一点是,==静态,这意味着它的重载被使用虚函数表(除非你使用dynamic在编译时进行,而不是在运行时间,但是这是一个整体的其他兽)。因此,只要您在代码中使用==运算符并且希望重载解析为您的自定义类型的运算符,就要注意这一点。

+0

如果在我的方法中使用派生约束。这改变了什么?我不能重载运算符像equals的对象? – 2011-01-31 12:23:58

1

如果您的方法参数被指定为object那么做param1 == param2只是执行引用相等,因为==运算符不是多态。

相关问题