Friday, November 11, 2011

IEqualityComparer with Linq

I was completely thrown by a simple Linq issue today.

I was reading in two lists of strings (user names as it happens) and I wanted to know which ones from the second list weren't in the first list. Simple problem right?
First stab was to iterate over the second list; if FirstList.Contains(string) then I wasn't interested in that entry but if it didn't contain that entry I was interested in it and would squirrel it away.
Multiple runs of this code provided a different number of results despite the source data being the same. Confusion reigned for a bit, scratched head and poked the code a few times until I realised I wasn't telling the .Contains call how to figure out if one string was the same as the other.
That sounds simple but C# wasn't making any assumptions, I don't know what the default equality comparer was doing but providing my own implementation of IEqualityComparer<T> (T was a string in my case) solved this problem.

I love the satisfaction of solving a problem like this but good grief I felt a bit silly to be stumped by something so simple : )
For full closure I really should have a go at finding out what the default comparer actually does, no time at the moment though.

EDIT (12th November, 2011): Spent some more time on it. I haven't found what the default comparer does yet however Microsoft have already created StringComparers for me.
This is an abstract class that has a couple of static properties that expose the concrete examples. In my case I would have used StringComparer.OrdinalIgnoreCase as my comparer instead of writing my own.

Thanks Microsoft : )

No comments: