按值对复杂类型进行分组

  • 本文关键字:类型 复杂 c# linq
  • 更新时间 :
  • 英文 :


我有这个对象:

notes:[ 
     { user: {
           name: "A",
           group:{
                id:1,
                name:"Group 1"
           }
     }, 
     { user: {
           name: "B",
           group:{
                id:1,
                name:"Group 1"
           }
    }]

我需要按组分组..所以我尝试了这个:

foreach (IGrouping<Group, Note> item in notes.GroupBy(n => n.User.Group))
{
    var groupName = item.Key.Name;
    foreach (var note in item)
    {
        //
    }
}

但是我遇到了一个问题,因为分组不起作用(我认为这是因为它使用引用对复杂类型进行分组)。如果我通过n.User.GroupId更改n.User.Group它就可以工作,但是如果我这样做,我将无法获得组名。

您需要在组类中覆盖 Equals 和 GetHashCode。 R# 为其生成此类代码:

public class Group
{
    public int GroupId { get; set; }
    public string Name { get; set; }
    protected bool Equals(Group other)
    {
        return GroupId == other.GroupId;
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Group) obj);
    }
    public override int GetHashCode()
    {
        return GroupId;
    }
}

是的,这是正确的。 默认情况下,类都是唯一的,但是您可以覆盖唯一性。

  1. 覆盖组对象上的Equals(object obj)GetHasCode()以实现您自己的相等
  2. 实现IEqualityComparer<Group>并将其作为第三个参数传递给 GroupBy 方法。

这里有几个选择:

  • 确保组对象的类实现 GetHashCode 和 Equals。实现这些可以像比较组内的 ID 一样简单
  • 按 id 分组,并获取分组中第一个用户的组名称。所有分组用户都属于同一组,因此名称将相同
  • 如果您无权访问组类的源代码,请根据包装的组的 id 按实现 GetHashCode 和 Equals 的包装器进行分组。

你利用比较匿名类的优势,写成

notes.GroupBy(n => new{n.User.Group.ID,n.User.Group.Name});

相关内容

  • 没有找到相关文章

最新更新