LINQ GroupBy自定义模型与匿名类型分组结果不一致问题咨询
LINQ GroupBy 自定义类型与匿名类型分组结果不一致的原因
LINQ的GroupBy方法依赖两个核心逻辑完成分组:对象相等性判断和哈希码计算,这也是两种类型分组结果不同的根本原因:
匿名类型的自动实现:C#编译器会自动为匿名类型生成
Equals和GetHashCode的重写逻辑,逻辑完全基于匿名类型的所有属性值。只要两个匿名实例的对应属性值全部相等,它们的Equals会返回true,且GetHashCode会生成相同的哈希码,因此GroupBy能正确将它们归为同一组。自定义类型的缺失实现:你的
GroupListModel只重写了Equals方法,但没有重写GetHashCode方法。GroupBy执行时,会先通过哈希码将元素分配到不同的"桶"中,只有哈希码相同的元素才会进一步用Equals做相等性校验。如果两个实例通过Equals判断是相等的,但哈希码不同,就会被分到不同的桶里,最终无法被归为同一组,导致分组结果不符合预期。
修复方案
必须为GroupListModel同时重写GetHashCode方法,哈希码的计算要基于Equals方法中用到的所有属性(保证相等的对象一定有相同的哈希码),示例代码如下:
public class GroupListModel { public string CardId { get; set; } public DateTime Date { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public override bool Equals(object? obj) { if (obj == null) return false; if (!(obj is GroupListModel)) return false; GroupListModel model = (GroupListModel)obj; return (this.CardId.Equals(model.CardId) && this.FirstName.Equals(model.FirstName) && this.LastName.Equals(model.LastName) && DateTime.Compare(this.Date, model.Date) == 0); } public override int GetHashCode() { // 结合所有参与相等判断的属性计算哈希码 return HashCode.Combine(CardId, Date, FirstName, LastName); } }
注意:
HashCode.Combine是.NET Core/.NET 5+提供的便捷方法,如果是旧版本.NET Framework,可以手动组合各属性的哈希值,比如:return (CardId?.GetHashCode() ?? 0) * 17 + Date.GetHashCode() * 23 + (FirstName?.GetHashCode() ?? 0) * 31 + (LastName?.GetHashCode() ?? 0) * 37;用质数相乘的方式能降低哈希碰撞的概率,比简单异或更稳妥。
内容的提问来源于stack exchange,提问作者Lukas Hieronimus Adler
相关产品推荐
相关产品推荐

