我正在使用List.Contains来判断一个变量是否在列表中,但是它一直在返回它不是在它之前。
我查了MSDN并且我注意到我必须从IEquatable继承并实现我自己的.Equals方法。实际的类继承自另一个类,所以我在基类中编写了.Equals方法。
以下是“Actividad”类的代码:
abstract public class Actividad:IEquatable<Actividad> {
protected int codigo;
[...]
public bool Equals(Actividad otra)
{
return this.Codigo == otra.Codigo;
}
}
这里是子类“Actividad_a”的定义:
public class Actividad_a : Actividad{ [...] }
这是检查列表中是否有内容的代码:
private void loadDisponibles() {
foreach (Actividad_a act in Program.Asignaturas) {
if (!user1.ActAcademicas.Contains(act)) {
doSomething();
}
}
}
Program.Asignaturas
和user1.ActAcademicas
都定义为List<Actividad_a>
。
问题是!user1.ActAcademicas.Contains(act)
总是返回true,无论数据是否在列表中。
我的第一个猜测是我必须继承IEquatable并在每个派生类中实现.Equals方法,但我不是很确定。
答案 0 :(得分:3)
您正在比较Actividad_a,而且Contains方法期望它实现IEquatable<Actividad_a>
而不是IEquatable<Actividad>
尝试覆盖默认的Equals方法
public override bool Equals(object otra)
{
var actividad = otra as Actividad;
if (actividad == null) return false;
return this.Codigo == actividad.Codigo;
}
编辑:
更多信息:.NET 4.0引入了处理泛型的灵活性,称为Contravariance和Covariance http://msdn.microsoft.com/en-us/library/dd799517.aspx
协变和逆变泛型类型参数提供更大 分配和使用泛型类型的灵活性。例如, 协变类型参数使您可以进行外观分配 很像普通的多态性。假设你有一个基类和一个 派生类,名为Base和Derived。多态性使您能够 将Derived的实例分配给Base类型的变量。同样的, 因为IEnumerable(Of T)接口的类型参数是 协变,您可以分配IEnumerable的实例 (IEnumerable(Of Derived)在Visual Basic中)到类型的变量 IEnumerable的
通常,协变类型参数可用作返回类型 委托人和逆变型参数可以用作 参数类型。对于接口,协变类型参数可以是 用作接口方法的返回类型和逆变 类型参数可以用作接口的参数类型 方法
出于某种原因IEquatable<T>
was not made contravariant以及原始方法无效的原因