【问题标题】:Internals of "equals" in .NET.NET 中“等于”的内部结构
【发布时间】:2009-10-20 18:35:29
【问题描述】:

我有一个愚蠢的怀疑。通常“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;
   }

}

【问题讨论】:

  • 我建议将您的 IComparable 问题作为一个单独的问题提出,因为它更像是一个设计问题,而您的主要问题更多地与 .NET 对象模型的内容有关。

标签: c# oop interface


【解决方案1】:

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

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

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

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

关于第二个问题,当存在用于比较两个实例的“相等性”的语义时,您应该使用 IEquatable&lt;T&gt;,而这两个实例与引用相等性分开。

当有用于订购商品的语义时,您应该实现 IComparableIComparable&lt;T&gt;。这意味着它们可以小于、大于或相等。

【讨论】:

  • 打败我吧 :) 我注意到关于重载的想法有些混乱,其中一个签名更具体但与另一个兼容。 (例如教授>对象)
  • 那我可以说重载是编译时多态性而覆盖是运行时多态性吗?
  • @generix:是的,你可以。阅读:wiki.answers.com/Q/…
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    如果您只想覆盖默认的 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()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-17
      • 1970-01-01
      • 2012-12-12
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多