Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Linq and grouping with custom object

Posted on: 2012-12-03

Depending of what you want to do, you may want to group by id or by more values. A common case is to group by a unique idenfier but also want to get some connexe information like let say having the name. For example, if we want to group every jobs that every body had in their life, we would like to group by userid. But we may want to have their full name.

 var groupedList = nonGroupedList.GroupBy(g=> new MyCustomGroupingClass(g.UserId, g.UserFullName)); 

This won't work because every MyCustomGroupingClass will be different from C# perspective. This is because Linq will compare every object and figure out that every MyCustomGroupingClass has a different object.

 var groupedList = nonGroupedList.GroupBy(g=> g.UserId); 

This would work, because an integer is comparable but it doesn't solve the need to have the user name.

The solution is hidden in the problem : comparing classes. We need to provide a way to compare. This can be done by providing an override to the Equals method of your grouping class.

 public class MyCustomGroupingClass { 
   public int ID { get; set; } 
   public string FullName { get; set; }

  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((MyCustomGroupingClass)obj); 
  } 

  protected bool Equals(MyCustomGroupingClass other) { 
    return ID.Equals(other.ID) && string.Equals(FullName, other.FullName); 
  }
} 

From here, you will be able to group without problem with Linq and your custom grouping class.