简体   繁体   English

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

[英]Why doesn't List.Contains work with my code?

I'm using List.Contains to tell whether a variable is inside the list or not, but it keeps on returning that it isn't when it is. 我正在使用List.Contains来判断一个变量是否在列表中,但它继续返回它不是它的时间。

I've looked up MSDN and I've noticed that I have to inherit from IEquatable and implement my own .Equals method. 我查了MSDN ,我注意到我必须从IEquatable继承并实现我自己的.Equals方法。 The actual class is inheriting from another one, so I've written the .Equals method in the base class . 实际的类继承自另一个,所以我在基类中编写了.Equals方法。

Here's the code of the class "Actividad": 这是“Actividad”类的代码:

abstract public class Actividad:IEquatable<Actividad> {

    protected int codigo;

    [...]

    public bool  Equals(Actividad otra)
    {
        return this.Codigo == otra.Codigo;
    }   
}

and here's the definition of the child class "Actividad_a": 这里是子类“Actividad_a”的定义:

public class Actividad_a : Actividad{ [...] }

This is the code that checks whether something is inside the list: 这是检查列表中是否有内容的代码:

private void loadDisponibles() {

    foreach (Actividad_a act in Program.Asignaturas) {

        if (!user1.ActAcademicas.Contains(act)) {
           doSomething();
        }
    }
}

Program.Asignaturas and user1.ActAcademicas are both defined as List<Actividad_a> . Program.Asignaturasuser1.ActAcademicas都定义为List<Actividad_a>

The problem is that !user1.ActAcademicas.Contains(act) always returns true, no matter the data is in the list or not. 问题是!user1.ActAcademicas.Contains(act)总是返回true,无论数据是否在列表中。

My first guess is that I have to inherit from IEquatable and implement .Equals method in each derived class, but I'm not really sure about it. 我的第一个猜测是我必须继承IEquatable并在每个派生类中实现.Equals方法,但我不是很确定。

You're comparing Actividad_a and the Contains method is expecting it to implement IEquatable<Actividad_a> rather than IEquatable<Actividad> 您正在比较Actividad_a,并且Contains方法期望它实现IEquatable<Actividad_a>而不是IEquatable<Actividad>

Try overriding the default Equals method as well 尝试重写默认的Equals方法

public override bool Equals(object otra)
{
    var actividad = otra as Actividad;
    if (actividad == null) return false;
    return this.Codigo == actividad.Codigo;
}   

EDIT: 编辑:

Some more info: .NET 4.0 introduced flexibility for working with generics called Contravariance and Covariance http://msdn.microsoft.com/en-us/library/dd799517.aspx 更多信息:.NET 4.0引入了使用称为Contravariance和Covariance的泛型的灵活性http://msdn.microsoft.com/en-us/library/dd799517.aspx

Covariant and contravariant generic type parameters provide greater flexibility in assigning and using generic types. 协变和逆变泛型类型参数在分配和使用泛型类型时提供了更大的灵活性。 For example, covariant type parameters enable you to make assignments that look much like ordinary polymorphism. 例如,协变类型参数使您可以进行与普通多态相似的分配。 Suppose you have a base class and a derived class, named Base and Derived. 假设您有一个基类和一个名为Base和Derived的派生类。 Polymorphism enables you to assign an instance of Derived to a variable of type Base. Polymorphism允许您将Derived的实例分配给Base类型的变量。 Similarly, because the type parameter of the IEnumerable(Of T) interface is covariant, you can assign an instance of IEnumerable (IEnumerable(Of Derived) in Visual Basic) to a variable of type IEnumerable 类似地,因为IEnumerable(Of T)接口的类型参数是协变的,所以可以将IEnumerable(IEnumerable(Of Derived)在Visual Basic中)的实例分配给IEnumerable类型的变量

In general, a covariant type parameter can be used as the return type of a delegate, and contravariant type parameters can be used as parameter types. 通常,协变类型参数可以用作委托的返回类型,逆变类型参数可以用作参数类型。 For an interface, covariant type parameters can be used as the return types of the interface's methods, and contravariant type parameters can be used as the parameter types of the interface's methods. 对于接口,协变类型参数可以用作接口方法的返回类型,逆变类型参数可以用作接口方法的参数类型。

For some reason IEquatable<T> was not made contravariant and why your original approach won't work 出于某种原因, IEquatable<T> 没有变成逆变 ,为什么你的原始方法不起作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM