在下面的例子中,我创建了一个名为'Custom'的类,它实现了IComparable:
public int CompareTo(Object value)
{
// comparison logic here
}
CompareTo(Object)的实现通常是“宽容”的,因为它们会将“值”转换为更具体的类型。在这种情况下,将执行“Custom”类型的强制转换,以便进行比较。想象一下,我也重载了==运算符:
public static bool operator== (Custom lhs, Custom rhs)
{
// equivalence test here
}
我遇到的问题是在这种情况下:
Custom c = GetCustomObject();
Object o = GetOtherObject();
if(c == o)
{
// will not be true unless c and o are the same object
}
问题是当调用==时,因为rhs是'Object'类型,它会回退到参考相等的默认测试 - 不会调用重载。
这里有什么期望?我可以为==运算符添加另一个重载:
public static bool operator== (Custom lhs, Object rhs)
但MSDN或其他在线示例中明显缺少此类示例。这让我认为参考相等性的测试是预期的行为
答案 0 :(得分:2)
这让我觉得参考相等性的测试是预期的行为
这是正确的。
以任何其他方式实现它是非常有用的,因为在变量的静态类型上调度了==
。如果您实施==(YourClass, Object)
,那么:
YourClass x = new YourClass();
if (x == someObject) { ... }
表现不同:
Object x = new YourClass();
if (x == someObject) { ... }
这通常是意料之外的!
所以,如果你想要几乎分派的平等,你应该使用Equals
。
System
中只有一种类型实现了具有不同参数类型的==
,并且它非常特殊(RuntimeTypeHandle)。
答案 1 :(得分:1)
(c == o) = false
完全可以预料到。记住,你正在超载!运营商。您的运算符重载public static bool operator== (Custom lhs, Custom rhs)
无效,因为您没有public static bool operator== (Custom lhs, Object rhs)
。现在你拥有它,它有点意义,对吧?
所以解决方案是使用接口或基类。无论如何,比较2个不相关的对象是没有意义的。正如您所知,.Net已经为您做好了。但是以自定义方式比较相关对象非常有意义:
public static bool operator== (ICustom x, ICustom y)
答案 2 :(得分:0)
也许对于一些特殊的密封类型组(或假装像字符串一样的值类型的引用类型),可能会提出==
object
作为短路的方法团体内部的平等。
我不希望这种比较适用于非密封类型(并且编译时错误是让人们知道某些东西不在这里的简单方法),因为有很多选项可以使这些代码在派生类中出现问题。参考比较应该足够了。
要让==
合理地工作,每种类型组合需要6次覆盖:(Custom,object)
,(Custom,Custom)
,(object,Custom,
以及两个运算符:==
/ { {1}}。
!=
要让它正常工作,您需要各种 public static bool operator != (object lhs, Custom rhs)
{
return !(lhs==rhs);
}
public static bool operator == (object lhs, Custom rhs)
{
// equivalence test here
return true;
}
和Equals
来匹配上述行为。