Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GroupBy with a known class as the grouping key [duplicate]

Tags:

c#

linq

grouping

We wanted to GroupBy with a known class as the grouping key. It doesn't seem to work - LINQ appears to need to group with an anonymous class.

  • Is it possible to use GroupBy with a known class as the grouping key?
  • If not, why not?
  • If so, how?

This question is different than Why does using anonymous type work and using an explicit type not in a GroupBy? because it asks how to use GroupBy with a known class.

Here is a fiddle that shows what works and what fails. The one that fails doesn't create a group.

public static void Works(EnumerableRowCollection<DataRow> dataRows)
{
    var grouped = dataRows.GroupBy(
        row => new {
            Name = row["Name"]
        }, 
        (k, g) => new {
            Key = k,
            Group = g.CopyToDataTable()
        });
}

public static void Fails(EnumerableRowCollection<DataRow> dataRows)
{
    var grouped = dataRows.GroupBy(
        row => new GroupingKey {
            Name = row["Name"]
        }, 
        (k, g) => new {
            Key = k,
            Group = g.CopyToDataTable()
        });
}
like image 863
Shaun Luttin Avatar asked May 04 '15 21:05

Shaun Luttin


1 Answers

The difference is in the way that comparison is performed on anonymous types vs. concrete types.

According to the GroupBy documentation:

The default equality comparer Default is used to compare keys.

For anonymous types, the default equality comparer uses a property-by-property comparison, so any two anonymous types with the same members and values will be considered equivalent.

For concrete types, the default equality comparer uses reference comparison, so any two instances of the object are always considered inequivalent, regardless of their values.

To make GroupBy work with your GroupingKey class, you can either use the overload that takes an IEqualityComparer<T> to define comparisons, or override Object.Equals in GroupingKey to perform the desired comparison.

like image 139
BJ Myers Avatar answered Oct 02 '22 22:10

BJ Myers