Operator overloading ==, !=, Equals
Solution 1
I think you declared the Equals
method like this:
public override bool Equals(BOX obj)
Since the object.Equals
method takes an object, there is no method to override with this signature. You have to override it like this:
public override bool Equals(object obj)
If you want type-safe Equals,
you can implement IEquatable<BOX>
.
Solution 2
As Selman22 said, you are overriding the default object.Equals
method, which accepts an object obj
and not a safe compile time type.
In order for that to happen, make your type implement IEquatable<Box>
:
public class Box : IEquatable<Box>
{
double height, length, breadth;
public static bool operator ==(Box obj1, Box obj2)
{
if (ReferenceEquals(obj1, obj2))
return true;
if (ReferenceEquals(obj1, null))
return false;
if (ReferenceEquals(obj2, null))
return false;
return obj1.Equals(obj2);
}
public static bool operator !=(Box obj1, Box obj2) => !(obj1 == obj2);
public bool Equals(Box other)
{
if (ReferenceEquals(other, null))
return false;
if (ReferenceEquals(this, other))
return true;
return height.Equals(other.height)
&& length.Equals(other.length)
&& breadth.Equals(other.breadth);
}
public override bool Equals(object obj) => Equals(obj as Box);
public override int GetHashCode()
{
unchecked
{
int hashCode = height.GetHashCode();
hashCode = (hashCode * 397) ^ length.GetHashCode();
hashCode = (hashCode * 397) ^ breadth.GetHashCode();
return hashCode;
}
}
}
Another thing to note is that you are making a floating point comparison using the equality operator and you might experience a loss of precision.
Solution 3
In fact, this is a "how to" subject. So, here is the reference implementation:
public class BOX
{
double height, length, breadth;
public static bool operator == (BOX b1, BOX b2)
{
if ((object)b1 == null)
return (object)b2 == null;
return b1.Equals(b2);
}
public static bool operator != (BOX b1, BOX b2)
{
return !(b1 == b2);
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
var b2 = (BOX)obj;
return (length == b2.length && breadth == b2.breadth && height == b2.height);
}
public override int GetHashCode()
{
return height.GetHashCode() ^ length.GetHashCode() ^ breadth.GetHashCode();
}
}
REF: https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx#Examples
UPDATE: the cast to (object)
in the operator ==
implementation is important, otherwise, it would re-execute the operator == overload, leading to a stackoverflow. Credits to @grek40.
This (object)
cast trick is from Microsoft String
== implementaiton.
SRC: https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/string.cs#L643
Solution 4
public class BOX
{
double height, length, breadth;
public static bool operator == (BOX b1, BOX b2)
{
if (b1 is null)
return b2 is null;
return b1.Equals(b2);
}
public static bool operator != (BOX b1, BOX b2)
{
return !(b1 == b2);
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
return obj is BOX b2? (length == b2.length &&
breadth == b2.breadth &&
height == b2.height): false;
}
public override int GetHashCode()
{
return (height,length,breadth).GetHashCode();
}
}
Sagar Kothari
iOS App Developer, Android App Developer, ReactJS Developer, Flutter
Updated on July 05, 2022Comments
-
Sagar Kothari almost 2 years
I've already gone through question
I understand that, it is necessary to implement
==
,!=
andEquals()
.public class BOX { double height, length, breadth; // this is first one '==' public static bool operator== (BOX obj1, BOX obj2) { return (obj1.length == obj2.length && obj1.breadth == obj2.breadth && obj1.height == obj2.height); } // this is second one '!=' public static bool operator!= (BOX obj1, BOX obj2) { return !(obj1.length == obj2.length && obj1.breadth == obj2.breadth && obj1.height == obj2.height); } // this is third one 'Equals' public override bool Equals(BOX obj) { return (length == obj.length && breadth == obj.breadth && height == obj.height); } }
I assume, I've written code properly to override
==
,!=
,Equals
operators. Though, I get compilation errors as follows.'myNameSpace.BOX.Equals(myNameSpace.BOX)' is marked as an override but no suitable method found to override.
So, question is - How to override above operators & get rid of this error?
-
epox about 7 years
-
grek40 over 6 yearsDon't write
if (null == b1)
, it will re-execute theoperator ==
overload, leading to a stackoverflow. Same forb2
. -
epox over 6 years@grek40 , will
if ((object)b1==null)
avoid the issue? -
grek40 over 6 yearsYes, this should do the trick. Alternative would be using
object.ReferenceEquals
like the other answer. -
Alex 75 about 5 yearsI think
(object)b1==null
could return a NullObjectException or InvalidCastException -
Peter Huber about 5 yearsFor HashCode generation, it is better to use a tupple.GetHashCode():
(height, length, breadth).GetHashCode()
. The problem with using XOR is that height, length, breadth probably use only the lower bits and the higher bits are unused. A hash ideally uses all 32 bits of the integer. This is achieved by bit-shifting the parameters by different values, which GetHashCode() does.