LINQ GroupBy求和未按预期工作问题求助
问题根源
你在GroupBy里用new tempClass { myKey = x.myKey }作为分组键,但tempClass是引用类型(类),.NET默认对引用类型的相等性判断是比较内存引用地址,而不是属性值。也就是说,哪怕两个tempClass实例的myKey完全相同,只要它们是不同的实例(每次new都会生成新的内存地址),GroupBy就会把它们当成不同的分组键,自然没法把相同myKey的项归到一组。
解决方案
这里给你三种可行的解决办法,按推荐程度排序:
方案1:直接用myKey值作为分组键(最简单高效)
既然你只需要按myKey分组,完全没必要创建新的tempClass实例当键,直接用int类型的myKey值就行——值类型的相等性判断是按实际值比较的,完美适配分组需求:
// 修正后的完整代码 var list = new List<tempClass>(); list.Add(new tempClass { myKey = 1, total = 1 }); list.Add(new tempClass { myKey = 1, total = 2 }); list.Add(new tempClass { myKey = 2, total = 3 }); list.Add(new tempClass { myKey = 2, total = 4 }); var groupedResult = list .GroupBy(x => x.myKey) // 直接用myKey值作为分组键 .Select(g => new tempClass { myKey = g.Key, total = g.Sum(item => item.total) // 对分组内的total求和 }) .ToList(); // 输出结果:myKey=1, total=3;myKey=2, total=7
方案2:给tempClass重写Equals和GetHashCode方法
如果后续需要按tempClass的多个属性分组,必须用类实例作为分组键的话,就得告诉.NET怎么判断两个tempClass实例是“相等”的。重写这两个方法,让判断逻辑基于myKey(如果有其他属性需要参与,也可以加进去):
public class tempClass { public int myKey { get; set; } public int total { get; set; } // 重写Equals,基于myKey判断相等 public override bool Equals(object obj) { if (obj is not tempClass other) return false; return myKey == other.myKey; } // 重写GetHashCode,确保相等的实例返回相同的哈希码 public override int GetHashCode() { return HashCode.Combine(myKey); } }
重写之后,你原来的GroupBy写法就能正常工作了,但这种方式比方案1繁琐,只在必要时使用。
方案3:用匿名类型作为分组键
匿名类型的Equals和GetHashCode方法是.NET自动根据其属性生成的,会按属性值判断相等性,所以也能实现正确分组:
var groupedResult = list .GroupBy(x => new { x.myKey }) // 匿名类型,自动按myKey值比较 .Select(g => new tempClass { myKey = g.Key.myKey, total = g.Sum(item => item.total) }) .ToList();
这种方式比方案2简洁,但不如方案1直接,适合需要同时按多个属性分组的场景。
总结
优先选方案1,它最直接、高效,完全贴合你的需求。方案2和3只在有特殊分组需求时考虑。
内容的提问来源于stack exchange,提问作者Pop
相关产品推荐
相关产品推荐

