我有一个用户列表及其注册日期。现在,我想按5分钟的间隔将用户的注册日期分组,如下所示:
Group 1
15:01
15:03
15:04
Group 2
15:06
15:06
Group 3
15:17
Group 4
15:59
我的问题是:为什么此解决方案给我正确的答案:
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();
但不是:
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; }
}
第二个解决方案返回7个组,每个组1个用户。
答案 0 :(得分:3)
这是因为您没有为Equals
类覆盖GetHashCode
和GroupCriteria
。调用GroupBy
时,通过共享同一键将项目分组。在指定的情况下,键是您创建的对象,并且相等性是针对该实例定义的相等性。为GroupCriteria
这样做时,它会通过默认定义的对象(对象的引用)检查对象的相等性。在为每个项目投影一个新对象时,引用将有所不同,并且组属于单个项目。
对于匿名对象(new {...}
),等于(equals)比较字段并因此起作用。有关此行为的更多信息,请阅读Why does the Equals implementation for anonymous types compare fields?。正如格特在该问题的回答中所述:
匿名类型上的Equals和GetHashcode方法会覆盖从对象继承的方法,并根据属性的Equals和GetHashcode进行定义,因此,当且仅当它们的所有属性都相同时,相同匿名类型的两个实例才相等相等。
答案 1 :(得分:2)
通过相等性比较创建的实例。对于第一个示例中的匿名类型instances are equal if the fields are,但在第二个示例中,相等性是通过引用获得的,因此,具有相同属性值的两个实例不视为相等,因此最终位于不同的组中。>