Why does using an anonymous type work and use an explicit type not in GroupBy?

I have a problem when I want a group type to be strongly typed, but if I do this, it does not group correctly. See code below ...

using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication35 { class Program { static void Main(string[] args) { List<Foo> foos = new List<Foo>(); foos.Add(new Foo() { Key = "Test" }); foos.Add(new Foo() { Key = "Test" }); foos.Add(new Foo() { Key = "Test" }); var groups = foos.GroupBy<Foo, dynamic>(entry => new { GroupKey = entry.Key }); Console.WriteLine(groups.Count()); groups = foos.GroupBy<Foo, dynamic>(entry => new GroupingKey() { GroupKey = entry.Key }); Console.WriteLine(groups.Count()); } public class Foo { public string Key { get; set; } } public class GroupingKey { public string GroupKey { get; set; } } } } 

Exit:

 1 3 Press any key to continue . . . 

I expect the result to be the same regardless of using an explicit type, but should not be just one group with 3 elements, not 3 groups with 1 element. What's going on here?

Update I added IEqualityComparer and it works now! See below:

 using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication35 { class Program { static void Main(string[] args) { List<Foo> foos = new List<Foo>(); foos.Add(new Foo() { Key = "Test" }); foos.Add(new Foo() { Key = "Test" }); foos.Add(new Foo() { Key = "Test" }); var groups = foos.GroupBy<Foo, dynamic>(entry => new //GroupingKey() { GroupKey = entry.Key }); Console.WriteLine(groups.Count()); groups = foos.GroupBy<Foo, GroupingKey>(entry => new GroupingKey() { GroupKey = entry.Key }, new GroupingKeyEqualityComparer()); Console.WriteLine(groups.Count()); } public class Foo { public string Key { get; set; } } public class GroupingKey { public string GroupKey { get; set; } } public class GroupingKeyEqualityComparer : IEqualityComparer<GroupingKey> { #region IEqualityComparer<GroupingKey> Members public bool Equals(GroupingKey x, GroupingKey y) { return x.GroupKey == y.GroupKey; } public int GetHashCode(GroupingKey obj) { return obj.GroupKey.GetHashCode(); } #endregion } } } 

Conclusion:

 1 1 Press any key to continue . . . 

This pretty much confirms the answer provided by JaredPar!

+6
source share
1 answer

In the first version, you create an anonymous type with a single property named GroupKey . Anonymous types in C # use structural equality, so equality of values ​​comes down to equality of keys. This forces them to group correctly.

In the second case, you are using a custom type named GroupingKey . This seems to be using standard or referential equality. Therefore, none of the instances is considered equal and, therefore, it falls into different groups.

+7
source

Source: https://habr.com/ru/post/900823/


All Articles