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).Default
forT
, the type of values in the list.
And from EqualityComparer<T>.Default
:
The
Default
property checks whether typeT
implements 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.Equals
andObject.GetHashCode
provided 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)).