【问题标题】:Grouping by anonymous v.s. grouping by non-anonymous按匿名 vs. 分组按非匿名分组
【发布时间】:2016-02-24 09:38:58
【问题描述】:

一些数据从服务器到达后,我需要对其进行分组。

var result = context.GetData();

Assert.Equal(54, result.Count); // OK

var transactions = result.GroupBy(t => new //BeneficiaryGroup
                        {
                            BankAcronym = t.BankAcronym.Substring(4, 4),
                            DebitDate = t.DebitDate,
                            Key = t.Key
                        })
                    .OrderBy(g => g.Key.BankAcronym)
                    .ThenBy(g => g.Key.DebitDate)
                    .ThenBy(g => g.Key.Key)
                    .ToList();

Assert.Equal( 14, transactions.Count ); // OK

当我按匿名对象分组时,分组已正确完成。

当我按 BeneficiaryGroup 对象分组时,具有完全相同的属性

public class BeneficiaryGroup 
{ 
    BankAcronym,
    DebitDate,
    Key
}

分组未正确完成 - 该组有 54 条记录,与分组前一样。

我想按一个类对数据进行分组,以便将已分组的集合返回给 API 使用者。

任何想法为什么会出现这种奇怪的行为?

【问题讨论】:

    标签: linq group-by


    【解决方案1】:

    匿名类型“免费”获得“合理”的平等行为,这就是分组在这种情况下按预期工作的原因。当您切换到使用命名类时,作为类定义者,您有责任提供相等行为,允许以您期望的方式将 BeneficiaryGroup 用作分组键。


    正如the docs for GroupBy 所说,

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

    其中DefaultEqualityComparer<T>.Default,这说明:

    Default 属性检查类型 T 是否实现 System.IEquatable<T> 接口,如果是,则返回一个 EqualityComparer<T> 使用该实现。否则,它 返回一个EqualityComparer<T>,它使用 Object.EqualsObject.GetHashCodeT 提供。

    还有for an anonymous type

    因为匿名类型的 EqualsGetHashCode 方法是 根据 EqualsGetHashCode 方法定义 属性,相同匿名类型的两个实例仅当 它们的所有属性都是相等的。

    而对于覆盖EqualsGetHashCode的命名类型,您将获得Object实现,这通常没有用处。

    【讨论】:

    • 确实,我应该考虑到这一点。
    猜你喜欢
    • 1970-01-01
    • 2018-09-14
    • 2012-07-19
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    相关资源
    最近更新 更多