重载的操作符参数始终为空
所以我有一个类重写Equals(object obj)和GetHashCode()以及实现IEquatable。为了使这种类型的工作在检查平等时更自然一些,我认为,嘿,我会超负荷平等运算符和不平等运算符,无后顾之忧......重载的操作符参数始终为空
呃哦,忧虑...考虑以下 - 其中两个实例的myType不为空:
if (myType != container.myType) //NullReferenceException
{
//never get here
}
//never get here either
现在,容器是另一个类以保存其中用于缓存项以外的东西的的myType一个实例。
下面是对的myType实际的(相关)代码:
public class MyType : IEquatable<MyType>
{
public static bool operator ==(MyType myTypeA, MyType myTypeB)
{
return myTypeA.Equals(myTypeB);
}
public static bool operator !=(MyType myTypeA, MyType myTypeB)
{
return !(myTypeA == myTypeB);
}
public override bool Equals(object obj)
{
if (obj != null && obj is MyType)
{
return Equals((MyType)obj);
}
return false;
}
public bool Equals(MyType other)
{
if (other != null)
{
return other.ToString() == ToString();
}
return false;
}
}
在这方面的经验吗?
谢谢。
棘手的......问题是,你使用等号平等覆盖内部如下:
public bool Equals(MyType other)
{
if (other != null)
它去你重载=操作符,这反过来去你的==操作符! ,它试图做null.Equals ...
这是一个常见的错误。或者使用'object.ReferenceEquals'或者'if((object)other!=(object)null){...}'将操作数(或者其中的一个)这是静态的(因此从未被覆盖)。 – 2013-07-24 08:24:33
两个指针 -
- 如果您已经撤消了对类
==
和!=
,确保使用ReferenceEquals
检查在过载实现中为null,而不是==
,因为这会调用您的重载操作符并进入循环或试图在空this
引用上调用Equals
,这可能是在这里发生的事情。 - 请勿覆盖类别上的
==
和!=
。这些运营商是为价值平等而设计的,而类别的设计并非真正具有价值平等。要么删除操作员重载,要么使结构成为一个结构。
谢谢,这样,并且在不遗漏调用的情况下逐步执行代码时的一点耐心,让我意识到Equals实际上被调用为null作为导致使用null调用相等运算符的比较,导致另一个等于null的呼叫,这导致另一个带有两个空值的平等运算符呼叫,以及BANG。可能会更糟糕,可能会有一个可怕的循环。 – 2010-10-03 16:30:58
正如其他人已经声明,你需要仔细检查空值,因为它会再次调用你的相等函数,通常导致*Exception。
当我使用IEquatable
接口类我通常使用下面的代码:
public override bool Equals(object obj)
{
// If obj isn't MyType then 'as' will pass in null
return this.Equals(obj as MyType);
}
public bool Equals(MyType other)
{
if (object.ReferenceEquals(other, null))
{
return false;
}
// Actual comparison code here
return other.ToString() == this.ToString();
}
你能后的堆栈跟踪?因为如果你得到一个NRE,东西必须是空的。你是如何验证这两个参数都不为空的? – 2010-10-03 15:10:50