如何在C# List中基于两个属性实现分组?
解决基于两个属性分组的问题
嘿,我懂你现在卡在哪了!你想按Dept和Area两个属性对员工列表做分组,但当前代码里的x.Dept && x.Area是逻辑与运算,它只会返回true或false,这自然没法按两个字段的组合来正确分组,只会把数据分成两组,完全不是你想要的结果。
下面给你几种正确的实现方式:
方法一:使用匿名类型作为分组键(最常用)
这是最简单直接的方式,匿名类型会自动把Dept和Area的组合作为唯一分组标识,只要两个字段的值都匹配,就会被分到同一组:
var result = EmpList .GroupBy(x => new { x.Dept, x.Area }) .Select(c => new { Key = c.Key, total = c.Count() });
你可以直接访问Key.Dept和Key.Area来获取分组的具体字段值。
方法二:使用自定义类/结构体作为分组键
如果需要在多个地方复用这个分组键的类型,可以定义一个具体的类,但必须重写Equals和GetHashCode方法,这样GroupBy才能正确识别相同的分组键:
// 定义分组键类 public class DeptAreaGroupKey { public string Dept { get; set; } public string Area { get; set; } // 重写相等判断方法 public override bool Equals(object obj) { if (obj is not DeptAreaGroupKey other) return false; return Dept == other.Dept && Area == other.Area; } // 重写哈希码方法 public override int GetHashCode() { return HashCode.Combine(Dept, Area); } } // 执行分组 var result = EmpList .GroupBy(x => new DeptAreaGroupKey { Dept = x.Dept, Area = x.Area }) .Select(c => new { Key = c.Key, total = c.Count() });
方法三:使用C# 9+的记录类型(更简洁)
如果你用的是C# 9或更高版本,推荐用记录类型——它默认已经实现了值相等性,不用手动重写Equals和GetHashCode:
// 定义记录类型的分组键 public record DeptAreaGroupKey(string Dept, string Area); // 执行分组 var result = EmpList .GroupBy(x => new DeptAreaGroupKey(x.Dept, x.Area)) .Select(c => new { Key = c.Key, total = c.Count() });
核心问题就是你之前误用了逻辑运算符&&,把分组键变成了布尔值,换成上面任意一种方式,就能按Dept和Area的组合正确分组啦!
内容的提问来源于stack exchange,提问作者Phanindra Maadesh
相关产品推荐
相关产品推荐

