【问题标题】:Override Equals and GetHashCode in class with one field用一个字段覆盖类中的 Equals 和 GetHashCode
【发布时间】:2011-08-10 13:31:48
【问题描述】:

我有一堂课:

public abstract class AbstractDictionaryObject
    {
        public virtual int LangId { get; set; }

        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != GetType())
            {
                return false;
            }

            AbstractDictionaryObject other = (AbstractDictionaryObject)obj;
            if (other.LangId != LangId)
            {
                return false;
            }

            return true;
        }

        public override int GetHashCode()
        {
            int hashCode = 0;               
            hashCode = 19 * hashCode + LangId.GetHashCode();
            return hashCode;
        }

而且我有派生类:

public class Derived1:AbstractDictionaryObject
{...}

public class Derived2:AbstractDictionaryObject
{...}

AbstractDictionaryObject 中只有一个公共字段:LangId
我认为这不足以(正确地)重载方法。
如何识别对象?

【问题讨论】:

    标签: c# overriding equals gethashcode


    【解决方案1】:

    一方面,您可以简化两种方法:

     public override bool Equals(object obj)
     {
         if (obj == null || obj.GetType() != GetType())
         {
             return false;
         }
    
         AbstractDictionaryObject other = (AbstractDictionaryObject)obj;
         return other.LangId == LangId;
     }
    
     public override int GetHashCode()
     {
         return LangId;
     }
    

    但到那时应该没问题。如果两个派生类有其他字段,它们应该自己覆盖GetHashCodeEquals,首先调用base.Equalsbase.GetHashCode,然后应用它们自己的逻辑。

    Derived1 的两个实例具有相同的LangIdAbstractDictionaryObject 而言将是等效的,Derived2 的两个实例也是如此 - 但它们彼此不同,因为它们具有不同的类型.

    如果您想为他们提供不同的哈希码,您可以GetHashCode() 更改为:

     public override int GetHashCode()
     {
         int hash = 17;
         hash = hash * 31 + GetType().GetHashCode();
         hash = hash * 31 + LangId;
         return hash;
     }
    

    然而,不同对象的哈希码必须不同......它只是有助于提高性能。如果您知道自己拥有具有相同LangId 的不同类型的实例,您可能想要这样做,否则我不会打扰。

    【讨论】:

    • “具有相同 LangId 的 Derived1 的两个实例将是等效的” - 这对我的情况不利。我可以介绍 GUID 字段吗?因为我不想在派生类中重写。
    • @user348173:如果您希望每个实例都不等于其他实例,那么您为什么要覆盖 Equals 和 GetHashCode 呢?目前尚不清楚您要达到的目标。什么时候应该认为两个不同的对象相等?
    • 如果 langId 相等且 Derived1 中存在的其他字段相等,则它们相等。
    • 例如,我有 Derived1 的两个实例:Class1 和 Class2。字段 LangId 相同,但其他字段(例如 - 名称)不同。所以 Class1 和 Class2 应该不相等。但我不想在 Derived1 中覆盖 Equals 和 GetHashCode。
    • @user348173:但是您应该覆盖 Derived1 中的 Equals 和 GetHashCode。您可以潜在地使用反射来检查字段,但这会很慢而且非常脆弱 - 您可能想要引入一个 不是 中平等契约一部分的字段派生1。从根本上说,基类无法预测类的哪些方面是其平等理念的一部分——因此您需要在每个派生类中提供这种行为。 为什么您不想在 Derived1 中覆盖 GetHashCode/Equals?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多