Home c# How GroupBy Works

How GroupBy Works

Author

Date

Category

Good day, everyone!
Please help me understand how GroupBy works and what is the difference between the code below.

class Employee {
  public string Name {get; set; }
  public string Id {get; set; }
  public string OfficeId {get; set; }
}
class Person {
  public string Name {get; set; }
  public string Id {get; set; }
}
class Program {
  static void Main (string [] args) {
    List & lt; Employee & gt; Employee = new List & lt; Employee & gt; () {
      new Employee {Id = "1", Name = "Alex", OfficeId = "1"},
      new Employee {Id = "2", Name = "John", OfficeId = "1"},
      new Employee {Id = "1", Name = "Alex", OfficeId = "2"},
      new Employee {Id = "2", Name = "John", OfficeId = "2"},
      new Employee {Id = "2", Name = "John", OfficeId = "3"},
    };
    var result1 = Employee.GroupBy (p = & gt; new {p.Id, p.Name});
    var result2 = Employee.GroupBy (p = & gt; new Person {Id = p.Id, Name = p.Name});
  }
}

In the case of result1, a collection with a similar type is created IEnumerable & lt; IGrouping & lt; AnonymousType & lt; string, string & gt ;, Employee & gt; & gt; where there are records with Id and Name keys. The element where Id = “1”, Name = “Alex” has two entries, the element where Id = “2”, Name = “John” has three entries, respectively.

I have no particular questions here and the structure of the object is as I expected to see it, but I needed to pass this object to the method as an argument and I created the Person class to replace the anonymous type.

In result2, a collection is created like this IEnumerable & lt; IGrouping & lt; Person, Employee & gt; & gt; and I can explicitly specify the type that the method should accept. The problem is that a list has been created here with five elements (keys) and each element has one value, which I did not expect and cannot understand why this is happening.

I would be grateful if they explain why there is such a difference in results, if instead of an anonymous type in GroupBy you specify a custom type and how to get an object with a data structure as in result1, but with an indication of a custom type.

P.S. If you specify grouping by one field in GroupBy (for example, Id), then the result will be that in result1 only the key will consist of a string, but what about when the key should be an object with several properties?


Answer 1, authority 100%

For anonymous types, the compiler automatically generates the Equals and GetHashCode methods, which:

are defined through the Equals and GetHashCode methods of properties, two instances of the same anonymous type are equal only if their properties are equal.

quote from here: Anonymous Types (C # Programming Guide)

Therefore, the following code will output True :

var x = new {Id = 1, Name = "Ivan"};
var y = new {Id = 1, Name = "Ivan"};
Console.WriteLine (x.Equals (y));

In the Person class, the Equals method is not overridden, so the implementation from the base Object class is used, which compares references.

References to different instances are of course not equal, so code like this will return False :

var x = new Person {Id = 1, Name = "Ivan"};
var y = new Person {Id = 1, Name = "Ivan"};
Console.WriteLine (x.Equals (y));

Thus, grouping in the second case will create a separate group for each Person instance.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions