Generic.List - Contains函数如何工作?

时间:2010-11-16 18:32:50

标签: .net .net-3.5

我有两个通用列表,其中包含相同的对象类型T。例如 oGenList1.Items(0)oGenList2.Items(3)相同(其属性具有相同的值等) 我正在做这样的事情:

oGenList2.Contains(oGenList1.Items(0))

始终显示false;我不明白为什么。你有什么主意吗? 我是否必须为类T定义任何比较器以强制此功能正常工作?

我已经添加了Equals功能但它仍然无效。 :( 我在一个非常简单的项目中对我的情况进行了简单的模拟,并且它有效。 但我的情况更复杂。我的类继承自其他类等。 知道为什么它可能不起作用吗?

2 个答案:

答案 0 :(得分:5)

默认情况下,它只是使用您的类型的Equals方法。您不需要定义自定义比较器;如果您的场景很简单(您只希望Contains正常运行),只需覆盖您的类型的Equals方法,根据您想要的标准比较两个对象是否相等,您应该是好的。 (哦,如果你要覆盖Equals,你也应该覆盖GetHashCode)。

基本示例:

class X : IEquatable<X>
{
    public int Value { get; set; }

    public bool Equals(X other)
    {
        return other != null && other.Value == Value;
    }

    // This is the main part you need to do. Otherwise by default
    // object.Equals just tests for reference equality.
    public override bool Equals(object obj)
    {
        return Equals(obj as X);
    }

    public override int GetHashCode()
    {
        return Value;
    }
}

public class Program
{
    public static void Main()
    {
        var list1 = new List<X> { new X { Value = 1 } };
        var list2 = new List<X> { new X { Value = 1 } };

        // Since type X overrides the Equals method to test
        // the equality of two instances' properties, this line
        // outputs True.
        Console.WriteLine(list2.Contains(list1[0]));
    }
}

答案 1 :(得分:2)

IIRC,这将使用EqualityComparer<T>.Default进行比较。首先测试您的类型T是否实现IEquatable<T> - 如果是,它将使用该接口和Equals(T)方法。否则它只会使用object.Equals(object)(请注意,它也会考虑nullNullable<T>,因此您不必这样做。

默认情况下,这意味着 classes 只有在相同的实例(在字段级别比较结构)时才会被视为相等。如果您覆盖Equals,您应该获得所期望的行为,但请注意,如果您覆盖Equals,则还应覆盖GetHashCode以实现类似的实施。