我的方法接收两个参数,都是Object
类型。它们具有相同的类型,实现IEquatable
。当我比较一个对象(类型)是否使用特定类的IEquatable?
我的问题是:当我这样做:param1 == param2
不框架比较使用特定类别的IEquatable
操作符重载或它使用了仅仅比较两个对象的内存指针object.Equals
?
这是最好的方法吗?是泛型和派生约束?
我的方法接收两个参数,都是Object
类型。它们具有相同的类型,实现IEquatable
。当我比较一个对象(类型)是否使用特定类的IEquatable?
我的问题是:当我这样做:param1 == param2
不框架比较使用特定类别的IEquatable
操作符重载或它使用了仅仅比较两个对象的内存指针object.Equals
?
这是最好的方法吗?是泛型和派生约束?
实际上,它既不。无论您的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);
以上内容不会像您所期望的那样工作(如果您已超载==
并期望使用),因为==
重载必须在编译时解决;由于x
和y
被键入为任意对象,因此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
上述方法将使用您的重载==
运营商任何类型T
从A
导出。
需要记住的重要一点是,==
是静态,这意味着它的重载被使用虚函数表(除非你使用dynamic
在编译时进行,而不是在运行时间,但是这是一个整体的其他兽)。因此,只要您在代码中使用==
运算符并且希望重载解析为您的自定义类型的运算符,就要注意这一点。
如果您的方法参数被指定为object
那么做param1 == param2
只是执行引用相等,因为==
运算符不是多态。
你必须重载equals过,甚至GetHashCode()方法:看看这里: http://blogs.msdn.com/b/jaredpar/archive/2009/01/15/if-you-implement-iequatable-t-you-still-must-override-object-s-equals-and-gethashcode.aspx
如果在我的方法中使用派生约束。这改变了什么?我不能重载运算符像equals的对象? – 2011-01-31 12:23:58