可能重复:
How do I check for nulls in an ‘==’ operator overload without infinite recursion?
我有一个看起来像这样的对象:
public class Tags
{
int mask;
public static bool operator !=(Tags x, Tags y)
{
return !(x == y);
}
public static bool operator ==(Tags x, Tags y)
{
return x.mask == y.mask;
}
}
这适用于将实例相互比较,但我也希望能够处理如下表达式:
if(tags1 == null)
执行此操作会在以下行中导致异常:
return x.mask == y.mask;
由于y
为null
。
我尝试将此功能更改为:
public static bool operator ==(Tags x, Tags y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
return x.mask == y.mask;
}
但是,这会产生堆栈溢出,因为实现使用自己的重写比较运算符。
让==
运算符处理与null
的比较的诀窍是什么?谢谢!
答案 0 :(得分:7)
根据guideline:
public static bool operator ==(Tags a, Tags b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return a.mask == b.mask;
}
答案 1 :(得分:6)
您可以使用x == null
或(object)x == null
代替Object.ReferenceEquals(x, null)
:
public static bool operator ==(Tags x, Tags y)
{
if ((object)x == null && (object)y == null) return true;
if ((object)x == null || (object)y == null) return false;
return x.mask == y.mask;
}
但您还应该实施Equals
和GetHashCode
:
public override bool Equals(object obj)
{
return this.Equals(obj as Tags);
}
public bool Equals(Tags tags)
{
return (object)tags != null && this.mask == tags.mask;
}
public override int GetHashCode()
{
return this.mask.GetHashCode();
}
现在可以简单地写出operator ==
:
public static bool operator ==(Tags x, Tags y)
{
return (object)x != null ? x.Equals(y) : (object)y == null;
}
答案 2 :(得分:0)
见question。使用Object.ReferenceEquals。
答案 3 :(得分:0)
Kirill给出了一个很好的答案,但是我使用某种改进的模式来实现运算符,包括以下列方式正确实现Equals()
和GetHashCode()
:
public static bool operator !=(MyType first, MyType second)
{
return !(first == second);
}
public static bool operator ==(MyType first, MyType second)
{
if (ReferenceEquals(first, null)
|| ReferenceEquals(second, null))
{
return ReferenceEquals(first, second);
}
return first.Equals(second);
}
public override bool Equals(object obj)
{
return Equals(obj as MyType);
}
public bool Equals(MyType other)
{
if (ReferenceEquals(other, null))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
// Check all simple properties
if (GetHashCode() != other.GetHashCode()
|| Name != other.Name
|| Age != other.Age
|| Phone != other.Phone)
{
return false;
}
return true;
}
public override int GetHashCode()
{
unchecked
{
var hash = 34591;
if (Name != null)
{
hash = hash * 29863 + Name.GetHashCode();
}
if (Phone != null)
{
hash = hash * 29863 + Phone.GetHashCode();
}
hash = hash * 29863 + Age;
return hash;
}
}
答案 4 :(得分:-1)
如果您可以考虑不使用运算符而不使用方法,则无法定义自己的扩展方法。像这样。
public static bool IsEqual(this Tags a, Tags b)
{
if(a == null && b == null)
return true;
if((a != null && b == null) || (a == null && b != null))
return false;
return b.mask == this.mask
}