Реализация оператора == в C# при реализации явного интерфейса

Я определил структуру 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

Однако, когда я выполняю сравнение на равенство с оператором == между значениями одного из типов интерфейса, как

if (coordsUser1 == userCoords2) { /* whatever */ }

всегда выполняется сравнение ссылок с использованием object.==. Кто-нибудь знает, как я могу принудительно установить равенство значений для оператора == в таких обстоятельствах, используя С#?

Заранее спасибо за любые мысли или предложения.

[Изменить] В приведенном выше примере и coordsUser1, и userCoords2 являются экземплярами Coords, хранящимися в переменных типа ICoordsUser. , поэтому мне непонятно, почему не используется определенное переопределение ==.


person Pieter Geerkens    schedule 26.02.2013    source источник


Ответы (1)


Поскольку вы не можете определить статические члены для интерфейса, вы не можете определить операторы для интерфейса. Поскольку перегрузка операторов разрешается во время компиляции, компилятор не увидит ни одного оператора ==, который соответствует сигнатуре данного типа интерфейса. Поскольку Object определяет оператор == для объектов, а лучшего совпадения во время компиляции не существует, он будет использовать именно его.

Есть три способа решить эту проблему:

  1. Приведите левый объект к типу, определяющему оператор ==.

    return (Coords)coordsUser1 == userCoords2;
    
  2. Используйте обычный метод Equals(object). Однако это будет упаковывать вашу структуру.

    return coordsUser1.Equals(userCoords2);
    
  3. Заставьте свои интерфейсы реализовать IEquatable<T> и используйте общий Equals(T) (который уменьшает упаковку).

    return coordsUser1.Equals(userCoords2);
    
person Daniel A.A. Pelsmaeker    schedule 26.02.2013
comment
Метод (3) — это то, что я использовал, когда задавался вопросом, есть ли альтернатива. - person Pieter Geerkens; 27.02.2013