为什么使用匿名类型工作并使用不在GroupBy中的显式类型?

我有一个问题,我希望组类型强类型,但如果我这样做不正确分组。 看下面的代码……

using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication35 { class Program { static void Main(string[] args) { List foos = new List(); foos.Add(new Foo() { Key = "Test" }); foos.Add(new Foo() { Key = "Test" }); foos.Add(new Foo() { Key = "Test" }); var groups = foos.GroupBy(entry => new { GroupKey = entry.Key }); Console.WriteLine(groups.Count()); groups = foos.GroupBy(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; } } } } 

输出:

 1 3 Press any key to continue . . . 

我希望结果是相同的,无论使用显式类型也不是,即应该只有一个组有3个项目而不是3组有1个项目。 这里发生了什么?

更新我添加了IEqualityComparer,它现在可以正常工作! 见下文:

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

输出:

 1 1 Press any key to continue . . . 

这几乎证实了JaredPar给出的答案!

在第一个版本中,您将创建一个匿名类型,其中包含一个名为GroupKey属性。 C#中的匿名类型使用结构相等,因此值的相等性归结为键的相等性。 这使它们正确地组合在一起。

在第二种情况下,您使用名为GroupingKey的自定义类型。 它似乎使用默认或引用相等。 因此,没有一个实例被认为是相同的,因此它们被分成不同的组。