1

我定义了一个结构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为 ,ICoordsUserICoordsCustom. 然后我在结构上定义了价值平等,如下所示:

#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.==进行参考比较。有谁知道在这种情况下如何使用 C#将值相等强制到==运算符上?

提前感谢您的任何想法或建议。

[编辑] 在上面的示例中,coordsUser1userCoords2都是存储在 ICoordsUser 类型变量中的Coords实例,所以我不清楚为什么不使用==的定义覆盖。

4

1 回答 1

5

由于您无法为接口定义静态成员,因此您无法在接口上定义运算符。因为运算符重载是在编译时解决的,所以编译器不会看到任何==与给定接口类型的签名匹配的运算符。由于Object定义了==对象的运算符,并且在编译时没有更好的匹配,它将使用那个。

有三种方法可以解决这个问题:

  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 回答