为什么List.Contains不能使用我的代码?

时间:2012-04-16 22:09:54

标签: c# list contains

我正在使用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.Asignaturasuser1.ActAcademicas都定义为List<Actividad_a>

问题是!user1.ActAcademicas.Contains(act)总是返回true,无论数据是否在列表中。

我的第一个猜测是我必须继承IEquatable并在每个派生类中实现.Equals方法,但我不是很确定。

1 个答案:

答案 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以及原始方法无效的原因