设计比较运算符时的StackOverflow

本文关键字:StackOverflow 运算符 比较 | 更新日期: 2023-09-27 18:01:42

根据这篇文章,我的Equal(Thing(如下所示。

public override int GetHashCode() { return Id.GetHashCode(); }
public override bool Equals(object input)
{
  Thing comparee = input as Thing;
  return comparee != null && comparee.Id == Id;
}
public static bool operator ==(Thing self, Thing other)
{
  return self != null && other != null && self.Id == other.Id;
}
public static bool operator !=(Thing self, Thing other)
{
  return self == null || other == null || self.Id != other.Id;
}

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

设计比较运算符时的StackOverflow

定义了一个比较Things的==运算符后,当您说someThing == null时就会使用它。与CCD_ 4类似。

所以,如果你说self == other,你最终会打电话给operator ==(self, other)。在你的标准中,你有self != null,它称为operator !=(self, null)。。。它检查是否为self == null,从而调用operator ==(self, null),然后一轮又一轮地循环,直到耗尽堆栈空间。

我确信您可以通过将内容转换为object来进行参考比较来解决此问题。或者,你可以说Object.ReferenceEquals(self, null)等等,它不依赖于==,所以你不会得到递归。

我完全同意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);
}

使用reference equal不会导致堆栈溢出异常,因为它不使用==/!=运算符,并且实现!=以简单地返回==运算符的!将在equity测试更改时为您节省维护。这是DRY原则的实现。