【问题标题】:Cannot use new HashCode to override GetHashCode in class无法使用新的 HashCode 覆盖类中的 GetHashCode
【发布时间】:2021-01-28 16:38:09
【问题描述】:

我复制了教授给我的代码,但出现错误“当前上下文中不存在名称 'HashCode”。我读到了一些东西,我认为它应该可以工作。我正在使用 VisualStudio 2019。该行在下面标记。

Visual 给我的潜在修复之一是安装包 Microsoft.Bcl.HashCode,但正如 Microsoft 文档所述,它应该已经在 System 中。

由于它是最近添加的,因此没有发现任何相关信息。有一些用途(和我的一样),但不知道为什么我的不起作用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LV6.Zad3 {
    public class Car : IEquatable<Car>
        {
        public string Make { get; private set; }
        public string Model { get; private set; }
        public int Km { get; private set; }
        public int Year { get; private set; }
        
        public Car(string brand, string type, int km, int year)
        {
            Make = brand;
            Model = type;
            Km = km;
            Year = year;
        }
        
        public override string ToString() => $"{Make} - {Model} - {Km} - {Year}";
        
        public override int GetHashCode() => HashCode.Combine(Make, Model, Km, Year);  // I this line <--
        
        public override bool Equals(object obj){
            if (obj is Car == false) return false;
            return this.Equals((Car) obj);
        }
        
        public bool Equals(Car other) => this.Make == other.Make &&
            this.Model == other.Model &&
            this.Year == other.Year &&
            this.Km == other.Km;
        
    }

}

【问题讨论】:

  • HashCode 是在 .NET Core 2.1 中引入的(请参阅“适用于”in the docs)。您的目标可能是 .NET Framework 或早期版本的 .NET Core。
  • Microsoft 文档说 System.HashCode.Combine() 函数从 .NET 5.0 开始可用。你用的是什么版本?
  • @canton7 .NET Core 不只是 .NET Framework 的一个子集吗?
  • @Josip 是的,您为此使用了什么 .NET?
  • @Quizzarex 不,不是。 .NET Core 是 .NET 的新版本,它取代了 .NET Framework

标签: c# hashcode


【解决方案1】:

答案在问题中,但由于我花了一分钟时间才解决问题,所以我会发布一个答案 - 微软的解决方案是正确的,你不能在 .Net Framework 中使用 System.Hashcode。

使用 nuget 中的 Microsoft.Bcl.HashCode 包,它会在旧框架 .net 版本的类中填充。

至于您遇到这种情况的原因,在不了解您的设置的情况下,您可能有具有不同 .net 版本的不同项目,或者您可能有一些 dll 已编译一半。

在 .net 4.8 及之前版本中,如果 System.Hashcode 存在,则它是内部的且不可公开访问,这是您的错误的根源。

【讨论】:

    【解决方案2】:

    如果 HashCode 不可用,因为这不是 .NET Core 应用程序,那么您可以使用自定义实现。以下示例基于on this accepted answer

    public class Car : IEquatable<Car>
    {
        public string Make { get; private set; }
        public string Model { get; private set; }
        public int Km { get; private set; }
        public int Year { get; private set; }
    
        public Car(string brand, string type, int km, int year)
        {
            Make = brand;
            Model = type;
            Km = km;
            Year = year;
        }
    
        public override string ToString() => $"{Make} - {Model} - {Km} - {Year}";
    
    
        #region IEquatable Members
        /// <summary>
        /// Equality overrides from <see cref="System.Object"/>
        /// </summary>
        /// <param name="obj">The object to compare this with</param>
        /// <returns>False if object is a different type, otherwise it calls <code>Equals(Car)</code></returns>
        public override bool Equals(object obj)
        {
            if (obj is Car other)
            {
                return Equals(other);
            }
            return false;
        }
    
        /// <summary>
        /// Checks for equality among <see cref="Car"/> classes
        /// </summary>
        /// <param name="other">The other <see cref="Car"/> to compare it to</param>
        /// <returns>True if equal</returns>
        public virtual bool Equals(Car other)        
            => this.Make == other.Make &&
            this.Model == other.Model &&
            this.Year == other.Year &&
            this.Km == other.Km;
        
    
        /// <summary>
        /// Calculates the hash code for the <see cref="Car"/>
        /// </summary>
        /// <returns>The int hash value</returns>
        public override int GetHashCode()
        {
            unchecked
            {
                int hc = -1817952719;
                hc = (-1521134295)*hc + Make.GetHashCode();
                hc = (-1521134295)*hc + Model.GetHashCode();
                hc = (-1521134295)*hc + Year.GetHashCode();
                hc = (-1521134295)*hc + Km.GetHashCode();
                return hc;
            }
        }
    
        #endregion
    
    }
    

    或者使用Tuple&lt;&gt;使用的哈希码组合

    // System.Tuple
    internal static int CombineHashCodes(int h1, int h2)
    {
        return ((h1 << 5) + h1) ^ h2;
    }
    

    【讨论】:

    • 这不是回答问题,只是展示了另一种为自定义对象实现散列的方法。
    • 还不如用官方实现的nuget包,而不是这个
    猜你喜欢
    • 1970-01-01
    • 2012-07-13
    • 2018-03-27
    • 2012-11-20
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多