Q:

Group by multiple keys and ignore case

When I try to do the following,
collection.GroupBy(item => new
                        {
                            item.Item1,
                            item.Item2,
                            item.Item3,
                            item.Item4
                        }, StringComparer.CurrentCultureIgnoreCase)

I get an error that the argument types cannot be inferred from the usage, and to try to specify the type arguments explicitly.
What is the right syntax for this?

A:

As the name suggests, the StringComparer is for comparing simple strings, not anonymous types.
From the MSDN page on StringComparer:

Represents a string comparison operation that uses specific case and culture-based or ordinal comparison rules.

To compare your class, you can create your own comparer:
public class CustomComparer : IEqualityComparer<SomeClass>
{
    public bool Equals(SomeClass x, SomeClass y)
    {
        return String.Equals(x.Item1, y.Item1, StringComparison.CurrentCultureIgnoreCase)
               && String.Equals(x.Item2, y.Item2, StringComparison.CurrentCultureIgnoreCase)
               && String.Equals(x.Item3, y.Item3, StringComparison.CurrentCultureIgnoreCase);
    }

    public int GetHashCode(SomeClass obj)
    {
        return string.Concat(obj.Item1.ToLower(),
                             obj.Item2.ToLower(),
                             obj.Item3.ToLower()).GetHashCode();
    }
}

And use it in the GroupBy:
var collection = new List<SomeClass>();

// populate collection

collection.GroupBy(item => item, new CustomComparer());

That should work, although you may need to play around with it.

