实现IEquatable时隐藏基类方法

时间:2014-08-22 16:36:56

标签: c# inheritance iequatable

我正在寻找实现IEquatable<T>的最佳方式,以便隐式进行类型检查。如果我在子课程中拨打Equals,我想确保I&amp; m比较的类型是相同的。请参阅下面的精简示例。

如果两个Child1对象的ID相同,则应视为相等。在此示例中,如果它们的ID相同,则调用child1.Equals(child2)将返回true,这不是预期的行为。我基本上希望强制Child1的实例使用需要Equals参数的Child1重载,而不仅仅是从与Child1相同的基类派生的参数

我开始认为我以错误的方式接近这一点。也许我应该在基类中保留Equals的实现,并确保this.GetType() == other.GetType()

  public abstract class BaseClass : IEquatable<BaseClass>
  {
    public int ID { get; set; }

    public bool Equals(BaseClass other)
    {
      return 
        other != null &&
        other.ID == this.ID;
    }
  }

  public sealed class Child1 : BaseClass
  {
    string Child1Prop { get; set; }

    public bool Equals(Child1 other)
    {
      return base.Equals(other as BaseClass);
    }
  }

  public sealed class Child2 : BaseClass
  {
    string Child2Prop { get; set; }

    public bool Equals(Child2 other)
    {
      return base.Equals(other as BaseClass);
    }
  }

3 个答案:

答案 0 :(得分:3)

如果您确实需要“强制Child1的实例使用需要Equals参数的Child1重载”,则可以使用C# Generics

public abstract class BaseClass<T> : IEquatable<T>
    where T : BaseClass<T>
{
    public int ID { get; set; }

    public bool Equals(T other)
    {
        return
            other != null &&
            other.ID == this.ID;
    }
}

public sealed class Child1 : BaseClass<Child1>
{
    string Child1Prop { get; set; }

    public bool Equals(Child1 other)
    {
        return base.Equals(other);
    }
}

public sealed class Child2 : BaseClass<Child2>
{
    string Child2Prop { get; set; }

    public bool Equals(Child2 other)
    {
        return base.Equals(other);
    }
}

这确保您的“Equals”方法只能使用其定义的类型调用。

答案 1 :(得分:0)

你能比较每种类型吗?

  return base.Equals(other as BaseClass) && this.GetType() is other.GetType();

这将比较变量实例化的实际类型。我在这里创建了一个.net小提琴:https://dotnetfiddle.net/rOeuuo

这是代码(在vb中)

Imports System

Public Module Module1
    Public Sub Main()
        dim x as testparent = new testchild1
        dim y as testparent = new testchild2

        if x.GetType() is y.Gettype() then
            console.writeline("they are the same type")
        else
            console.writeline("they are different types")
        end if


    End Sub


End Module

public class testparent
    end class


    public class testchild1: inherits testparent

    end class


public class testchild2: inherits testchild1

    end class

这是另一个小提琴,其中两个子类直接从基类继承,而不是彼此继承(我认为这是你原来的问题):https://dotnetfiddle.net/ViNqej

Imports System

Public Module Module1
    Public Sub Main()
        dim x as testparent = new testchild1
        dim y as testparent = new testchild2

        if x.GetType() is y.Gettype() then
            console.writeline("they are the same type")
        else
            console.writeline("they are different types")
        end if


    End Sub


End Module

public class testparent
    end class


    public class testchild1: inherits testparent

    end class


public class testchild2: inherits testparent

    end class

答案 2 :(得分:0)

这里有几个选项:

  1. 您可以在此检查每个Equals方法中的实际运行时类型,并验证它不是您自己建议的子类型。这实际上是一个合理的解决方案。

  2. 您可以将每个Equals方法设为虚拟。让每个派生类型覆盖其父Equals方法,并静态return false或尝试强制转换为&#34;您的&#34;如果可以,请输入return false

  3. 使用==运算符代替Equals。它的定义可能会也可能不会检查操作数的运行时类型,并验证它们不是子类型。

  4. 此处的一个关键行为是,您不必尝试阻止您的类型的用户将您的对象与另一种类型的对象进行比较。除了崩溃之外,你实际上有一个明智的行为。你可以return false。你可以比较老虎和大象。它们有所不同,但你可以比较它们。