Reputation: 11883
I have defined a struct Coords that explicitly implements three interfaces, each defined like this:
public partial struct Coords
{
int ICoordsUser.X { get { return VectorUser.X; } }
int ICoordsUser.Y { get { return VectorUser.Y; } }
IntVector2D ICoordsUser.Vector { get { return VectorUser; }
set { VectorUser=value; } }
ICoordsCanon ICoordsUser.Canon { get { return this; } }
ICoordsUser ICoordsUser.Clone() { return NewUserCoords(VectorUser); }
string ICoordsUser.ToString() { return VectorUser.ToString(); }
IEnumerable<NeighbourCoords> ICoordsUser.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsUser.Range(ICoordsUser coords) { return Range(coords.Canon); }
}
with the names ICoordsCanon
, ICoordsUser
, and ICoordsCustom
. Then I have defined Value Equality on the struct like so:
#region Value Equality
bool IEquatable<Coords>.Equals(Coords rhs) { return this == rhs; }
public override bool Equals(object rhs) {
return (rhs is Coords) && this == (Coords)rhs;
}
public static bool operator == (Coords lhs, Coords rhs) {
return lhs.VectorCanon == rhs.VectorCanon;
}
public static bool operator != (Coords lhs, Coords rhs) { return ! (lhs == rhs); }
public override int GetHashCode() { return VectorUser.GetHashCode(); }
bool IEqualityComparer<Coords>.Equals(Coords lhs, Coords rhs) { return lhs == rhs; }
int IEqualityComparer<Coords>.GetHashCode(Coords coords) {
return coords.GetHashCode();
}
#endregion
However, when I perform an equality comparison with the == operator between values of one of the interface types, as
if (coordsUser1 == userCoords2) { /* whatever */ }
a reference comparison using object.== is always performed. Does anyone know how I can force value equality onto the == operator in such a circumstance, using C#?
Thank you in advance for any thoughts or suggestions.
[Edit] In the example above, both coordsUser1 and userCoords2 are instances of Coords stored in variables of type ICoordsUser, so it is not clear to me why the defined override of == is not being used.
Upvotes: 1
Views: 406
Reputation: 50326
Since you cannot define static members for an interface, you cannot define operators on an interface. Because operator overloading is resolved at compile-time, the compiler will not see any ==
operator that matches the signature given an interface type. Since Object
defines the ==
operator for objects, and there is no better match at compile time, it will use that one.
There are three ways to solve this:
Cast the left-hand object to the type that defines the ==
operator.
return (Coords)coordsUser1 == userCoords2;
Use the normal Equals(object)
method. However, this will box your struct.
return coordsUser1.Equals(userCoords2);
Force your interfaces to implement IEquatable<T>
, and use the generic Equals(T)
(which reduces boxing).
return coordsUser1.Equals(userCoords2);
Upvotes: 5