それぞれ次のように定義された 3 つのインターフェイスを明示的に実装する struct Coordsを定義しました。
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); }
}
ICoordsCanon
、ICoordsUser
、およびの名前が付いていますICoordsCustom
。次に、次のように構造体に値の等価性を定義しました。
#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
ただし、インターフェイス型の 1 つの値の間で==演算子を使用して等値比較を実行すると、次のようになります。
if (coordsUser1 == userCoords2) { /* whatever */ }
object.==を使用した参照比較は常に実行されます。このような状況で、C# を使用して==演算子に値の等価性を強制する方法を知っている人はいますか?
ご意見やご提案をお寄せいただきありがとうございます。
[編集] 上記の例では、coordsUser1とuserCoords2の両方がICoordsUser型の変数に格納されたCoordsのインスタンスであるため、定義された==のオーバーライドが使用されていない理由が明確ではありません。