GroupBy使用已知类作为分组键[重复]

时间:2022-09-10 07:35:05

This question already has an answer here:

这个问题在这里已有答案:

We wanted to GroupBy with a known class as the grouping key. It doesn't seem to work - LINQ appears to need to group with an anonymous class.

我们希望GroupBy使用已知类作为分组键。它似乎不起作用 - LINQ似乎需要与匿名类组合。

  • Is it possible to use GroupBy with a known class as the grouping key?
  • 是否可以将GroupBy与已知类一起用作分组键?

  • If not, why not?
  • 如果没有,为什么不呢?

  • If so, how?
  • 如果是这样,怎么样?

This question is different than Why does using anonymous type work and using an explicit type not in a GroupBy? because it asks how to use GroupBy with a known class.

这个问题与为什么使用匿名类型工作和使用不在GroupBy中的显式类型不同?因为它询问如何将GroupBy与已知类一起使用。

Here is a fiddle that shows what works and what fails. The one that fails doesn't create a group.

这是一个小提琴,显示哪些有效,哪些无效。失败的那个不会创建一个组。

public static void Works(EnumerableRowCollection<DataRow> dataRows)
{
    var grouped = dataRows.GroupBy(
        row => new {
            Name = row["Name"]
        }, 
        (k, g) => new {
            Key = k,
            Group = g.CopyToDataTable()
        });
}

public static void Fails(EnumerableRowCollection<DataRow> dataRows)
{
    var grouped = dataRows.GroupBy(
        row => new GroupingKey {
            Name = row["Name"]
        }, 
        (k, g) => new {
            Key = k,
            Group = g.CopyToDataTable()
        });
}

1 个解决方案

#1


The difference is in the way that comparison is performed on anonymous types vs. concrete types.

区别在于对匿名类型与具体类型进行比较的方式。

According to the GroupBy documentation:

根据GroupBy文档:

The default equality comparer Default is used to compare keys.

默认的相等比较器Default用于比较键。

For anonymous types, the default equality comparer uses a property-by-property comparison, so any two anonymous types with the same members and values will be considered equivalent.

对于匿名类型,默认的相等比较器使用逐个属性的比较,因此具有相同成员和值的任何两个匿名类型将被视为等效。

For concrete types, the default equality comparer uses reference comparison, so any two instances of the object are always considered inequivalent, regardless of their values.

对于具体类型,默认的相等比较器使用引用比较,因此对象的任何两个实例始终被视为不等价,而不管它们的值如何。

To make GroupBy work with your GroupingKey class, you can either use the overload that takes an IEqualityComparer<T> to define comparisons, or override Object.Equals in GroupingKey to perform the desired comparison.

要使GroupBy与GroupingKey类一起使用,您可以使用带有IEqualityComparer 的重载来定义比较,或者覆盖GroupingKey中的Object.Equals以执行所需的比较。

#1


The difference is in the way that comparison is performed on anonymous types vs. concrete types.

区别在于对匿名类型与具体类型进行比较的方式。

According to the GroupBy documentation:

根据GroupBy文档:

The default equality comparer Default is used to compare keys.

默认的相等比较器Default用于比较键。

For anonymous types, the default equality comparer uses a property-by-property comparison, so any two anonymous types with the same members and values will be considered equivalent.

对于匿名类型,默认的相等比较器使用逐个属性的比较,因此具有相同成员和值的任何两个匿名类型将被视为等效。

For concrete types, the default equality comparer uses reference comparison, so any two instances of the object are always considered inequivalent, regardless of their values.

对于具体类型,默认的相等比较器使用引用比较,因此对象的任何两个实例始终被视为不等价,而不管它们的值如何。

To make GroupBy work with your GroupingKey class, you can either use the overload that takes an IEqualityComparer<T> to define comparisons, or override Object.Equals in GroupingKey to perform the desired comparison.

要使GroupBy与GroupingKey类一起使用,您可以使用带有IEqualityComparer 的重载来定义比较,或者覆盖GroupingKey中的Object.Equals以执行所需的比较。