1

それぞれ次のように定義された 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); }
  }

ICoordsCanonICoordsUser、およびの名前が付いています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# を使用して==演算子に値の等価性を強制する方法を知っている人はいますか?

ご意見やご提案をお寄せいただきありがとうございます。

[編集] 上記の例では、coordsUser1userCoords2の両方がICoordsUser型の変数に格納されたCoordsのインスタンスであるため、定義された==のオーバーライドが使用されていない理由が明確ではありません。

4

1 に答える 1

5

インターフェイスの静的メンバーを定義できないため、インターフェイスで演算子を定義することはできません。==演算子のオーバーロードはコンパイル時に解決されるため、コンパイラは、指定されたインターフェイス型のシグネチャに一致する演算子を認識しません。Objectはオブジェクトの演算子を定義しており、コンパイル時に一致するものがないため==、それを使用します。

これを解決するには、次の 3 つの方法があります。

  1. 左側のオブジェクトを、==演算子を定義する型にキャストします。

    return (Coords)coordsUser1 == userCoords2;
    
  2. 通常のEquals(object)方法を使用してください。ただし、これは構造体をボックス化します。

    return coordsUser1.Equals(userCoords2);
    
  3. インターフェイスに を実装しIEquatable<T>、ジェネリックを使用するように強制しますEquals(T)(これにより、ボクシングが減少します)。

    return coordsUser1.Equals(userCoords2);
    
于 2013-02-26T20:51:21.010 に答える