重写Object.Equals并实现IEquatable<>?

时间:2015-06-30 12:25:17

标签: c# equality iequatable unreachable-code

我现在有点困惑。根据我的理解,.NET运行时将选择最适合给定参数类型的重载方法。所以我认为,在下面的代码段中,方法Equals(object obj)永远不会使用类型为Entry的实例调用。相反 - 因为存在具有正确参数类型的方法Equals(Entry other) - 它将被调用。

documentation for IEquatable on MSDN表示

  

如果实现IEquatable,还应该覆盖Object.Equals(Object)和GetHashCode的基类实现,以使它们的行为与IEquatable.Equals方法的行为一致。如果你重写了Object.Equals(Object),那么在你的类上调用静态Equals(System.Object,System.Object)方法时也会调用被覆盖的实现。

我的问题是:

  1. 是否正确,以下Equals(object obj)方法永远不会使用Entry类型的实例调用?
  2. 在下面的return false方法中仅仅Equals(object obj)是不是足够了?
  3. 如果是这样,为什么编译器不能将下面的注释行识别为无法访问?
  4. 我所指的代码:

    sealed class Entry : IEquatable<Entry> {
        ...
        // Overrides Object.Equals
        public override bool Equals(object obj)
        {
            if (obj is Entry)
            {
                return this.Equals(obj as Entry); // Is this code reachable?
            }
            return false;
        }
    
        // Implements IEquatable<Entry>.Equals
        public bool Equals(Entry other)
        {
            return this.Hash.Equals(other.Hash)
                && this.Path.Equals(other.Path)
                && this.Order.Equals(other.Order);
        }
    
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
    

    先谢谢你的帮助!

1 个答案:

答案 0 :(得分:4)

  

是否正确,下面的Equals(object obj)方法永远不会使用Entry类型的实例调用?

没有。考虑:

object entry1 = new Entry(...);
object entry2 = new Entry(...);
bool equal = entry1.Equals(entry2);

entry2的编译时类型为object,而非Entry,因此仍会调用Equals(object)

(请注意,顺便提一下,你的GetHashCode实现是狡猾的 - 而且你现在无法防范任何地方的空值。我们不知道Entry是否是一个类或一个结构。)