我有两个通用列表,其中包含相同的对象类型T
。例如
oGenList1.Items(0)
与oGenList2.Items(3)
相同(其属性具有相同的值等)
我正在做这样的事情:
oGenList2.Contains(oGenList1.Items(0))
始终显示false
;我不明白为什么。你有什么主意吗?
我是否必须为类T
定义任何比较器以强制此功能正常工作?
我已经添加了Equals功能但它仍然无效。 :( 我在一个非常简单的项目中对我的情况进行了简单的模拟,并且它有效。 但我的情况更复杂。我的类继承自其他类等。 知道为什么它可能不起作用吗?
答案 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)
EqualityComparer<T>.Default
进行比较。首先测试您的类型T
是否实现IEquatable<T>
- 如果是,它将使用该接口和Equals(T)
方法。否则它只会使用object.Equals(object)
(请注意,它也会考虑null
和Nullable<T>
,因此您不必这样做。
默认情况下,这意味着 classes 只有在相同的实例(在字段级别比较结构)时才会被视为相等。如果您覆盖Equals
,您应该获得所期望的行为,但请注意,如果您覆盖Equals
,则还应覆盖GetHashCode
以实现类似的实施。