这是我正在尝试做的一个例子:
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方法,这将导致调度相应方法的等式调用.此外,EqualityComparar< T> .Default(大多数集合类型用于进行相等性检查)已经具有智能以适当地选择IEquatable(self)或者object.Equals(object).
只要我能看到,尝试在基类中创建一个只转发请求的相等性的实现,就是没有添加任何值.
没有进一步的解释为什么你需要基类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; } }