这是关于我要执行的操作的一个示例:

public class Foo : IEquatable<Foo>
{
    public bool Equals(Foo other)
    {
        Type type1 = this.GetType();
        Type type2 = other.GetType();

        if (type1 != type2)
            return false;

        if (type1 == typeof(A))
        {
            A a = (A)this;
            A b = (A)other;

            return a.Equals(b);
        }
        else if (type1 == typeof(B))
        {
            B c = (B)this;
            B d = (B)other;

            return c.Equals(d);
        }
        else
        {
            throw new Exception("Something is wrong");
        }
    }
}

public class A : Foo, IEquatable<A>
{
    public int Number1 { get; set; }
    public int Number2 { get; set; }

    public bool Equals(A other)
    {
        return this.Number1 == other.Number1 && this.Number2 == other.Number2;
    }
}

public class B : Foo, IEquatable<B>
{
    public int Number1 { get; set; }
    public int Number2 { get; set; }
    public int Number3 { get; set; }

    public bool Equals(B other)
    {
        return this.Number1 == other.Number1 && this.Number2 == other.Number2 && this.Number3 == other.Number3;
    }
}

但是正如您在上面看到的那样,我必须使用许多条件'if'来标识实际类型。问题是我必须使用基类。例如:
A a = new A();
Foo foo = a;

foo.Equals(another);

最佳答案

作为您问题的直接答案,您似乎总是通过延迟(具体)子类的IEquatable<Foo>实现来实现IEquatable<self>。看起来像这样:

(错误代码,仅用于演示)

// You need to specify what you want when this method is called on a
// vanilla Foo object. I assume here that Foo is abstract. If not, please
// specify desired behaviour.
public bool Equals(Foo other)
{
    if (other == null || other.GetType() != GetType())
        return false;

    // You can cache this MethodInfo..
    var equalsMethod = typeof(IEquatable<>).MakeGenericType(GetType())
                                           .GetMethod("Equals");

    return (bool)equalsMethod.Invoke(this, new object[] { other });
}

但是,实际上并不清楚为什么需要相等比较才能始终“通过”基类的IEquatable<self>实现。

该框架已经具有虚拟的Equals方法,该方法将导致将相等调用分派(dispatch)到适当的方法。另外,EqualityComparar<T>.Default(大多数收集类型用于进行相等性检查的)已经可以根据需要选择IEquatable<self>.Equals(self)object.Equals(object)

据我所知,试图在仅转发请求的基类中创建平等的实现,对任何东西都没有增加任何值(value)。

在无需进一步说明为什么需要基类IEquatable<>实现的情况下,我建议仅在每种类型上正确实现相等性。例如:
public class A : Foo, IEquatable<A>
{
    public int Number1 { get; set; }
    public int Number2 { get; set; }

    public bool Equals(A other)
    {
        return other != null
            && Number1 == other.Number1
            && Number2 == other.Number2;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as A);
    }

    public override int GetHashCode()
    {
        return Number1 ^ Number2;
    }
}

09-25 16:44