【发布时间】:2009-10-19 15:30:57
【问题描述】:
具体是哪个类中的方法负责List<T>的Contains()操作?
我在课堂上重载了 ==。不过好像没什么效果。
【问题讨论】:
-
这里有一些很好的答案。为什么不接受一个....
-
我忘记接受了。
标签: c# contains generic-list
具体是哪个类中的方法负责List<T>的Contains()操作?
我在课堂上重载了 ==。不过好像没什么效果。
【问题讨论】:
标签: c# contains generic-list
它只会调用Equals() - 这就是所有需要被覆盖的东西(或者不,如果你对参考身份比较感到满意的话)。如果该类型实现了IEquatable<T>,那么该实现将优先于通用Equals(object)。
特别是来自List<T>.Contains 的文档:
此方法使用以下方法确定相等性 默认相等比较器
EqualityComparer(T).Default为T, 列表中值的类型。
来自EqualityComparer<T>.Default:
Default属性检查是否 类型T实现System.IEquatable(T)通用接口 如果是这样返回一个EqualityComparer(T)使用它 执行。否则返回EqualityComparer(T)使用 覆盖Object.Equals和Object.GetHashCode由T提供。
我不相信它会使用GetHashCode。
【讨论】:
根据 .NET 指南 - 如果您实现 == 始终提供 object.Equals() 和 != 运算符的实现。原因是运算符不是任何接口的一部分,并且不允许在泛型实现中使用它们(List 类不能在 T 上调用 == 运算符,因为不能保证 T 将定义运算符(参见结构示例) )。
【讨论】:
它会调用Object.Equals(),或者,如果你已经实现,IEquatable<T>.Equals():
private static EqualityComparer<T> CreateComparer()
{
Type c = typeof(T);
if (c == typeof(byte))
{
return (EqualityComparer<T>) new ByteEqualityComparer();
}
if (typeof(IEquatable<T>).IsAssignableFrom(c))
{
return (EqualityComparer<T>) typeof(GenericEqualityComparer<int>).TypeHandle.CreateInstanceForAnotherGenericParameter(c);
}
if (c.IsGenericType && (c.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
Type type2 = c.GetGenericArguments()[0];
if (typeof(IEquatable<>).MakeGenericType(new Type[] { type2 }).IsAssignableFrom(type2))
{
return (EqualityComparer<T>) typeof(NullableEqualityComparer<int>).TypeHandle.CreateInstanceForAnotherGenericParameter(type2);
}
}
return new ObjectEqualityComparer<T>();
}
【讨论】: