Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现IEquatable时隐藏基类方法_C#_Inheritance_Iequatable - Fatal编程技术网

C# 实现IEquatable时隐藏基类方法

C# 实现IEquatable时隐藏基类方法,c#,inheritance,iequatable,C#,Inheritance,Iequatable,我正在寻找实现IEquatable的最佳方法,即类型检查是隐式的。如果我在子类中调用Equals,我希望确保我要比较的类型是相同的。请参见下面的简化示例 如果两个Child1对象的ID相同,则应将其视为相等。在本例中,如果调用child1.Equalschild2的ID相同,则将返回true,这不是预期的行为。基本上,我希望强制Child1的实例使用需要Child1参数的Equals重载,而不仅仅是从与Child1相同的基类派生的参数 我开始觉得我用错误的方式来处理这个问题。也许我应该将Equa

我正在寻找实现IEquatable的最佳方法,即类型检查是隐式的。如果我在子类中调用Equals,我希望确保我要比较的类型是相同的。请参见下面的简化示例

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

我开始觉得我用错误的方式来处理这个问题。也许我应该将Equals的实现留在基类中,并确保this.GetType==other.GetType


你能比较一下每一种的类型吗

  return base.Equals(other as BaseClass) && this.GetType() is other.GetType();
这将比较变量实例化为的实际类型。我创建了一个.net小提琴,位于以下位置:

下面是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
这里还有一个问题,两个子类直接从基类继承,而不是相互继承我想这是你最初的问题:


您在这里有几个选项:

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

您可以使每个Equals方法成为虚拟的。让每个派生类型重写其父级的Equals方法,并静态返回false,或者尝试强制转换到您的类型,如果不能,则返回false

使用==运算符而不是等于。它的定义可能希望也可能不希望检查操作数的运行时类型并验证它们不是子类型


这里的一个关键行为是,您不必试图阻止您类型的用户将您的对象与另一类型的对象进行比较。你其实有一个明智的行为,而不仅仅是撞车。您可以返回false。你可以比较老虎和大象。它们是不同的,但您当然可以对它们进行比较。

如果您确实需要强制Child1的实例使用需要Child1参数的等于重载,您可以使用:


这确保了Equals方法只能使用其在中定义的类型调用。

如果您明确希望使用非虚拟相等运算符,请使用==运算符而不是Equals。也就是说,实际上Equals方法比较论点的类型并验证它不是一个子类型是一种常见的做法。这可以解决部分问题,但我不认为单独这样做就能完全解决问题,因为如果我在Child1和Child2之间调用Equals,它将直接跳到基类中的实现。如果我将你的建议添加到小提琴中注释的base Equals函数中,这确实提供了我想要的功能。那么答案是两者都做?这就是我的意思。示例fiddle只是为了证明GetType方法不能解析为基类。在.Equals中,比较两个对象的ID和类型以确定相等性。
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
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
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);
    }
}