Reputation: 1159
I have a list of users and their registration date. Now I want to group users by their registration date by 5-minute intervals, like this:
Group 1
15:01
15:03
15:04
Group 2
15:06
15:06
Group 3
15:17
Group 4
15:59
My question is: why this solution Is giving me right answer:
var users = GetUsers();
var interval = 5;
var registerInvervals = users.GroupBy(x => new
{
Month = x.Registered.Month,
Day = x.Registered.Day,
Hour = x.Registered.Hour,
MinuteFrom = (x.Registered.Minute/interval)*interval,
MinuteTo = (((x.Registered.Minute / interval) * interval) + 5)%61
})
.ToList();
but this not:
var users = GetUsers();
var interval = 5;
var registerInvervals = users.GroupBy(x => new GroupCriteria()
{
Month = x.Registered.Month,
Day = x.Registered.Day,
Hour = x.Registered.Hour,
MinuteFrom = (x.Registered.Minute/interval)*interval,
MinuteTo = (((x.Registered.Minute / interval) * interval) + 5)%61
})
.ToList();
class GroupCriteria
{
public int Month { get; set; }
public int Day { get; set; }
public int Hour { get; set; }
public int MinuteFrom { get; set; }
public int MinuteTo { get; set; }
}
The second solution returns 7 group with 1 user in each.
Upvotes: 2
Views: 117
Reputation: 37299
That is because you do not override Equals
and GetHashCode
for your GroupCriteria
class. When calling GroupBy
items are grouped by sharing the same key. In the specified case the key is the object you create and the equality is by the equality defined for that instance. When doing so for GroupCriteria
it checks the objects equality by the default one defined - their references. As you project a new object for each item then the references are different and the groups are of a single item.
As for anonymous objects (new {...}
) the equals compares the fields and thus works. For more about this behavior you can read Why does the Equals implementation for anonymous types compare fields?. As stated in Gert's answer in that question:
The Equals and GetHashcode methods on anonymous types override the methods inherited from object, and are defined in terms of the Equals and GetHashcode of the properties, so that two instances of the same anonymous type are equal if and only if all their properties are equal.
Upvotes: 3
Reputation: 18201
The created instances are compared by equality. For the anonymous type in your first example, instances are equal if the fields are, but in your second example, equality is by reference, so two instances with the same values of the properties are not considered equal, thus end up in different groups.
Upvotes: 2