设计比较运算符时的StackOverflow

时间:2016-08-10 05:18:04

标签: c# equals operator-keyword

根据this article,我附上 Equal(Thing),如下所示。

{{1}}

问题在于,在我添加运算符重定义之前它正在工作,现在我得到了StackOverflowException。我错过了什么?

2 个答案:

答案 0 :(得分:5)

定义比较==的{​​{1}}运算符后,当您说Thing时将使用该someThing == null运算符。与!=一样。

因此,如果您说self == other,则最终会调用operator ==(self, other)。在你的标准中,你有self != null,它会调用operator !=(self, null) ...来检查self == null,从而调用operator ==(self, null),然后绕过你直到你用完了堆栈空间。

我非常确定您可以通过将内容转换为object来进行参考比较。或者,您可以说Object.ReferenceEquals(self, null)等,它不依赖于==,因此您不会获得递归。

答案 1 :(得分:3)

我完全同意cHao的回答,但是在这种情况下我还想提出另一点,所以我将如何实现它:

public static bool operator ==(Thing self, Thing other)
{
    return !ReferenceEquals(self, null) && 
           !ReferenceEquals(other, null) && 
           self.Id == other.Id;
}

public static bool operator !=(Thing self, Thing other)
{
    return !(self == other);
}

使用引用相等不会导致堆栈溢出异常,因为它不使用== / !=运算符,并实现!=只返回!如果相等测试发生变化,==运算符将保存您的维护。这是DRY原则的实现。