You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定义基于双键分组的IGrouping类型

问题解决方法

方案一:使用具名类替代匿名类型(推荐)

匿名类型无法作为公开属性的泛型参数,所以你需要定义一个具名类作为分组键,并且必须重写Equals和GetHashCode方法(或实现IEquatable<T>),否则GroupBy无法正确识别相同的分组条件。

  1. 定义AccountInfo类并实现相等性判断:
public class AccountInfo : IEquatable<AccountInfo>
{
    public string Id { get; }
    public string Name { get; }

    public AccountInfo(string id, string name)
    {
        Id = id;
        Name = name;
    }

    // 基于属性值判断对象相等
    public bool Equals(AccountInfo other)
    {
        if (other is null) return false;
        return Id == other.Id && Name == other.Name;
    }

    // 基于属性值生成哈希码
    public override int GetHashCode()
    {
        return HashCode.Combine(Id, Name);
    }

    // 重写父类Equals方法,调用强类型判断逻辑
    public override bool Equals(object obj)
    {
        return Equals(obj as AccountInfo);
    }
}
  1. 修改属性的泛型参数:
public List<IGrouping<AccountInfo, License>> LicensesInfo
{
    get;
    set;
}
  1. 执行分组并赋值:
LicensesInfo = licenses.GroupBy(x => new AccountInfo(x.Id, x.Name)).ToList();

方案二:使用ValueTuple(C# 7.0+)

如果不想自定义类,可以用ValueTuple作为分组键,它默认实现了基于属性值的相等性判断:

  1. 修改属性定义:
public List<IGrouping<(string Id, string Name), License>> LicensesInfo
{
    get;
    set;
}
  1. 分组时直接使用ValueTuple:
LicensesInfo = licenses.GroupBy(x => (x.Id, x.Name)).ToList();

为什么之前用AccountInfo分组没生效?

默认情况下,Equals和GetHashCode是基于对象引用判断相等的——即使两个AccountInfo的Id和Name完全一致,它们也是不同的对象实例,GroupBy会把它们当成不同的分组键。必须重写这两个方法,让相等性判断基于属性值而非引用。

内容的提问来源于stack exchange,提问作者Quest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:06:19