You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何基于对象属性生成的HashCodeOnProperties返回值为0?

问题原因分析

你的代码返回0的核心问题在于异或(^)运算的特性:相同数值的哈希码异或结果为0,而你的Request对象里存在多组重复属性值(比如NorthEastLatitude和NorthWestLatitude值完全一致,SouthEastLatitude和SouthWestLatitude值也一致),这些重复值的哈希码两两异或后相互抵消,最终累加结果就变成了0。

另外,GetProperties()返回的属性顺序是不确定的(取决于反射实现),这也会导致相同属性值的对象可能生成不同哈希码,不符合哈希码的一致性要求。

修复方案

方案1:使用.NET内置的HashCode.Combine(推荐)

.NET提供了专门的HashCode结构体来安全组合多个值的哈希码,避免异或的缺陷,同时保证稳定性:

public static class HashCodeByPropertyExtensions
{
    public static int GetHashCodeOnProperties<T>(this T inspect)
    {
        var hashCode = new HashCode();
        // 对属性按名称排序,保证顺序稳定
        foreach (var prop in inspect.GetType().GetProperties().OrderBy(p => p.Name))
        {
            var value = prop.GetValue(inspect);
            hashCode.Add(value);
        }
        return hashCode.ToHashCode();
    }
}

方案2:手动实现哈希组合(兼容旧版本.NET)

如果使用的是.NET Framework等不支持HashCode结构体的版本,可以用传统的乘法累加方式,减少重复值抵消的概率:

public static class HashCodeByPropertyExtensions
{
    public static int GetHashCodeOnProperties<T>(this T inspect)
    {
        unchecked // 允许溢出,符合哈希码的设计原则
        {
            int hash = 17;
            // 对属性按名称排序,保证顺序稳定
            foreach (var prop in inspect.GetType().GetProperties().OrderBy(p => p.Name))
            {
                var value = prop.GetValue(inspect);
                hash = hash * 23 + (value?.GetHashCode() ?? 0);
            }
            return hash;
        }
    }
}

额外优化说明

  • 属性排序:反射获取的属性顺序不固定,排序后能保证相同属性值的对象无论反射顺序如何,生成的哈希码一致。
  • null值处理:通过value?.GetHashCode() ?? 0避免null引用异常,同时给null分配固定哈希值。

内容的提问来源于stack exchange,提问作者Zoinky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:57:38