Precisely which methods in a Class are responsible for the List<T>'s Contains() to operate?
I have overloaded == in my class. But it seems to have no effect.
Precisely which methods in a Class are responsible for the List<T>'s Contains() to operate?
I have overloaded == in my class. But it seems to have no effect.
It will just call Equals() - that's all that needs to be overridden (or not, if you're happy with reference identity comparisons). If the type implements IEquatable<T> then that implementation will be used in preference to the general Equals(object) though.
In particular, from the documentation for List<T>.Contains:
This method determines equality using the default equality comparer
EqualityComparer(T).DefaultforT, the type of values in the list.
And from EqualityComparer<T>.Default:
The
Defaultproperty checks whether typeTimplements theSystem.IEquatable(T)generic interface and if so returns anEqualityComparer(T)that uses that implementation. Otherwise it returns anEqualityComparer(T)that uses the overrides ofObject.EqualsandObject.GetHashCodeprovided byT.
I don't believe it will use GetHashCode at all though.
It will either call Object.Equals() or, if you have implemented, 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>();
}
From the .NET guidelines - if you implement == always provide an implementation for object.Equals() and the != operator. The reason is that operators are not part of any interface and their use is not allowed in generic implementations (a List class cannot call the == operator on T because there is no guarantee that T will have the operator defined (see structs for example)).