C # equality operators override (== and! =)

Possible duplicate:
How to check zeros in overloading operator '== without infinite recursion?

I have an object that looks like this:

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; } } 

This is great for comparing instances with each other, but I also want to be able to handle the expression, for example:

 if(tags1 == null) 

Doing this throws an exception on the following line:

 return x.mask == y.mask; 

Since y is null .

I tried changing this function to:

 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; } 

However, this creates a stack overflow because the implementation uses its own overridden comparison operator.

What trick is getting the == operator to compare with null ? Thanks!

+6
source share
5 answers

According to the recommendation :

 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; } 
+7
source

Instead of x == null you can use (object)x == null or 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; } 

But you must also implement Equals and 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(); } 

Now operator == can simply be written:

 public static bool operator ==(Tags x, Tags y) { return (object)x != null ? x.Equals(y) : (object)y == null; } 
+6
source

See question . Uses Object.ReferenceEquals.

0
source

Kirill gave a good answer, but I use some kind of improved scheme to implement the operators, including the correct implementation of Equals() and GetHashCode() as follows:

 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; } } 
0
source

If you can think that instead of using operators other than methods, you cannot define your own extension method. Like this.

 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 } 
-1
source

Source: https://habr.com/ru/post/907194/


All Articles