LINQ GroupBy对象还是只有匿名类型?

时间:2012-02-24 15:29:40

标签: .net linq

我知道LINQ可以通过利用匿名类型进行分组,所以如果我使用自己的对象进行分组,它也会分组。但是,它不是(至少在我的用法中)。

例如,使用我想要的两个参数的以下匿名类型组:

.GroupBy(v => new { v.GroupId })

但是一旦我使用自己的对象,它就不再进行分组了:

.GroupBy(v => new MyGrouping { GroupId = v.GroupId })

使用以下对象

 private class MyGrouping : IMyGrouping
 {
     public int GroupId { get; set; }

     public override bool Equals(object obj) { return Equals((MyGrouping)obj); }
     public bool Equals(MyGrouping obj)
     {
         return this.GroupId == obj.GroupId ;
     }
 }

我在自己的对象中遗漏了什么,还是不支持?


正如每张海报所指出的那样,我的Equals实现存在缺陷,因此我使用Resharper推荐的等式检查对其进行了修改,只是为了与预期不同并按预期进行分组。

 private class MyGrouping : IMyGrouping
 {
     public int GroupId { get; set; }

     public override bool Equals(object obj)
     {
         var myGrouping = obj as MyGrouping;
         return myGrouping != null ? Equals(myGrouping) : false;
     }
     public bool Equals(MyGrouping other)
     {
         if (ReferenceEquals(null, other)) return false;
         if (ReferenceEquals(this, other)) return true;
         return other.GroupId == GroupId;
     }

     public override int GetHashCode()
     {
         return GroupId;
     }
 }

对我来说,这是一个失败者,因为我的目标是减少代码......我之前的实现是通过动态变量进行分组,所以我现在可以重新考虑这个。

2 个答案:

答案 0 :(得分:4)

MyGrouping类肯定存在一些问题。

首先,如果调用它,则覆盖的Equals方法具有无限递归,因为您从未将对象强制转换为特定类型。其次,您不会覆盖GetHashCode()方法(如果您覆盖Equals(),则应始终执行此操作)。第三,如果您要为特定类型实施自定义Equals方法,则还应将IEquatable<T>接口添加到您的班级。

我的课程看起来像:

private class MyGrouping : IMyGrouping, IEquatable<IMyGrouping>
{
    public int GroupId { get; set; }

    public override bool Equals(object obj)
    {
        if(obj == null) return false;
        if(GetType() != obj.GetType()) return false;
        return Equals(obj as MyGrouping);
    }

    public override bool GetHashCode()
    {
        return GroupId.GetHashCode();
    }

    public bool Equals(IMyGrouping obj)
    {
        if(obj == null) return false;
        return GroupId == obj.GroupId;
    }
}

答案 1 :(得分:1)

首先,你的Equals覆盖很糟糕,首先尝试使用:

public override bool Equals(object obj)
{
  if (obj == null)
     return false;
  if (this.GetType() != obj.GetType())
     return false;
  return this.GroupID == ((MyGrouping)obj).GroupId;
}