C#相等运算符重写(==和!=)
本文关键字:重写 运算符 | 更新日期: 2023-09-27 18:21:45
可能重复:
如何在没有无限递归的情况下检查"=="运算符重载中的null?
我有一个看起来像这样的对象:
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;
由于CCD_ 1是CCD_。
我已经尝试将此功能更改为:
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
的比较有什么诀窍?谢谢
根据指南:
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;
}
您可以使用(object)x == null
或Object.ReferenceEquals(x, null)
:而不是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();
}
现在y
0可以简单地写:
public static bool operator ==(Tags x, Tags y)
{
return (object)x != null ? x.Equals(y) : (object)y == null;
}
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;
}
}
请参阅此问题。使用Object.ReferenceEquals.
如果你可以考虑不使用运算符而是使用方法,你就不能定义自己的扩展方法吗。就像这样。
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
}