Question

IEnumberable has an extension method Contains<T> which takes two parameters. The first parameter is the value to check for and the second is an implementation of IEqualityComparer. Looking at IEqualityComparer.Equals it takes two parameters named x and y, for the first and second objects to compare.

My question is X or Y the value from the IEnumerable?

Example

List<string> test = new List<String() { "a", "b", "c" };
test.Contains("d", myComparer);

When it calls to the Equals method for the first value will it be Equals("a","d") or Equals("d","a")?

Was it helpful?

Solution

It shouldn't matter - equality should be symmetric. From the docs for IEqualityComparer<T>.Equals:

The Equals method is reflexive, symmetric, and transitive. That is, it returns true if used to compare an object with itself; true for two objects x and y if it is true for y and x; and true for two objects x and z if it is true for x and y and also true for y and z.

I don't believe the usage in Enumerable.Contains is well-defined, i.e. it could change in a future version. If you just make your equality comparer obey the interface documentation, you'll be fine.

OTHER TIPS

For the sake of completeness the reflected code of IEnumberable shows it is on the left hand side (see below). However that is not promised not to ever change, so there is risk in using it.

public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
{
    if (comparer == null)
    {
        comparer = EqualityComparer<TSource>.Default;
    }
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    foreach (TSource local in source)
    {
        if (comparer.Equals(local, value))
        {
            return true;
        }
    }
    return false;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top