.NET中“等于”的内部结构

时间:2009-10-20 18:35:29

标签: c# oop interface

我有一个愚蠢的怀疑。一般来说,“System.Object”实现了“Equals”。当我实施 IEquatable接口我可以给我的“Equals”提供自定义定义(我相信如此)。

所以教授类的实现等于

class Professor:System.Object,IEquatable

因为System.Equals和IEquatable的Equals有不同的定义,为什么没有C#报告错误?。因为我没有覆盖“Equals”,甚至没有使用new关键字隐藏“Equals”。

class Professor : IEquatable<Professor>
{

   public string Name { get; set; }

   public bool Equals(Professor cust)
   {
       if (cust == null) return false;
       return cust.Name == this.Name;
   }

}

3 个答案:

答案 0 :(得分:8)

您既不会覆盖也不会隐藏Object.Equals() ,因为您的版本将教授作为参数类型 - 而不是对象。您的 overloading 是Equals()方法。

C#允许两个具有相同名称的方法在它们接受的参数类型上有所不同。这被称为重载 - 它可以被视为编译时多态性。

Overriding (您可以,也可能也应该这样做)从基类中的版本改变方法的实现。它是运行时类型多态的基础。

Hiding 是一种不太常见的技术,它允许派生类掩盖基类中某个方法的版本。根据您通过其进行调用的引用类型,您可以 获取基类版本(如果通过基类引用调用)或派生类版本(如果通过派生类型调用)参考)。

关于第二个问题,当存在用于比较两个与参考相等的实例的“相等”的语义时,应该使用IEquatable<T>

当存在订购商品的语义时,您应该实施IComparableIComparable<T>。意思是它们可以小于,大于或等同。

答案 1 :(得分:1)

Object.Equals方法接受“object”类型的对象作为其参数。您的Equals方法接受“教授”类型的对象作为其参数。这两种方法都可以共存,因为通过参数列表区分两个同名方法是合法的。这是调用方法重载。

答案 2 :(得分:1)

如果您只想覆盖默认的Equals()实现,则无需显式实现IEquatable。

你可以这样做:

class Professor
{

   public string Name { get; set; }

   public override bool Equals(object cust)
   {
       if (cust == null || !(cust is Professor)) return false;
       return cust.Name == this.Name;
   }

}

请注意,如果重写Equals(),则还应覆盖GetHashCode()以确保字典和其他使用散列来区分对象的集合的正确操作。这是MSDN页面guidelines for overriding Equals()