3

I have copied the code that the professor gave me, and I got the error "The name 'HashCode does not exist in the current context". I read about it something and I think it should work. I am using VisualStudio 2019. The line is marked down below.

One of the potential fixes that Visual gives me is to Instal package Microsoft.Bcl.HashCode, but as Microsoft documentation says, it should be in System already.

Didn't found anything about this since it is recently added. There are some uses (same as mine), but don't know why mine doesn't work.

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;
        
    }

}

  • 5
    `HashCode` was introduced in .NET Core 2.1 (see "Applies to" [in the docs](https://learn.microsoft.com/en-us/dotnet/api/system.hashcode?view=dotnet-plat-ext-5.0)). You're probably targetting .NET Framework, or an earlier version of .NET Core. – canton7 Jan 28 '21 at 16:39
  • The Microsoft documentation says that the function System.HashCode.Combine() is available since .NET 5.0. What version do you use ? – Bioukh Jan 28 '21 at 16:44
  • @canton7 Isn't .NET Core just a subset of .NET Framework? – Quizzarex Jan 28 '21 at 16:47
  • @Josip Yes, what .NET are you utilising for this? – Quizzarex Jan 28 '21 at 16:48
  • I used 4.7.2. Downloaded and installed 5.0 now. Do I need to create a new project now? I tried to reset Visual Studio and change the target framework in the existing project, and it's not listing 5.0. – Josip Maričević Jan 28 '21 at 16:49
  • @Bioukh No, it says it's available since .NET Core 2.1. See "Applies to" [here](https://learn.microsoft.com/en-us/dotnet/api/system.hashcode.combine?view=dotnet-plat-ext-5.0). .NET Core comes after .NET Framework and before .NET 5, so .NET Core 2.1 is older than .NET 5. – canton7 Jan 28 '21 at 17:10
  • 1
    @Quizzarex No it isn't. .NET Core is a new version of .NET, which supercedes .NET Framework – canton7 Jan 28 '21 at 17:10
  • @JosipMaričević If you created an old .NET Framework project, yes you'll need to re-create it – canton7 Jan 28 '21 at 17:12

2 Answers2

1

The answer is in the question but since it took me a minute to work it out I'll post an answer - the microsoft solution is correct, you cannot use System.Hashcode in .Net Framework.

Use the Microsoft.Bcl.HashCode package from nuget, it shims in the class for the older framework .net versions.

As for why you are experiencing this, without knowing a lot more about your setup, you likely have different project with different .net versions, or you may have some dlls half compiled.

In .net 4.8 and before, if System.Hashcode exists, it is internal and not publicly accessible, which is the source of your error.

smaudet
  • 609
  • 8
  • 17
-2

If HashCode isn't available because this is not a .NET Core app, then you can use a custom implementation. Example below based 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

}

Or use the hash code combination that Tuple<> uses

// System.Tuple
internal static int CombineHashCodes(int h1, int h2)
{
    return ((h1 << 5) + h1) ^ h2;
}
JAlex
  • 1,486
  • 8
  • 19