-2

Let's say I have a class with Name and Type properties, If I store the hashcode as below in a database, can I compare this hashcode in another process which has same name and type?

will the hashcode be same?

Name.ToLower().GetHashCode() + Type.ToLower().GetHashCode();
9
  • 2
    What's wrong with just storing the actual value? Commented Nov 15, 2021 at 18:00
  • 5
    No, definitely NOT guaranteed. Never do that. Read the "Warning" box in the documentation. The top item is literally Do not serialize hash code values or store them in databases. Commented Nov 15, 2021 at 18:01
  • 1
    Don't store hash codes returned by GetHashCode. The underlying implementation may change over time. During the lifetime of a process, it must return the same hash code for the same value or else dictionaries would break (for example). But between process lifetimes, the upgrade of the runtime (or a library) could change the algorithm and result in different hash codes and what's in your database wouldn't match. Commented Nov 15, 2021 at 18:03
  • 1
    design was demanding this ← What does that mean? Is that a person? What was the exact requirement? Maybe it was to use hash codes but not necessarily GetHashCode()? In that case there are many different hash implementations that you could use. Commented Nov 15, 2021 at 18:07
  • 1
    In .NET Core 3.1, .NET 5 and .NET 6, running the same program twice, with something as simple as Console.WriteLine("Test".GetHashCode()); will produce different outputs. Commented Nov 15, 2021 at 18:09

1 Answer 1

0

No, they will not, but look towards the end here for a more durable solution that might fit your needs.

First, there's the warning in the documentation:

Warning
A hash code is intended for efficient insertion and lookup in collections that are based on a hash table. A hash code is not a permanent value. For this reason:

  • Do not serialize hash code values or store them in databases.
  • Do not use the hash code as the key to retrieve an object from a keyed collection.
  • Do not send hash codes across application domains or processes. In some cases, hash codes may be computed on a per-process or per-application domain basis.
    ...

There's more in the warning but the last one illustrates a rather good point.

Simply create a small program with this code:

Console.WriteLine("Test".GetHashCode());

Then run this for .NET Core 3.1, .NET 5 or .NET 6, repeatedly.

You'll get different values

So to answer your question, no, they will not stay the same.

However, you can roll your own implementation. Here's a rather simple implementation of a hashcode function for strings that would only change if you change it yourself:

public static int SemiStableHashCode(string input)
{
    unchecked
    {
        byte[] bytes = Encoding.UTF8.GetBytes(input.Normalize(NormalizationForm.FormKD));
        int result = 17;
        foreach (byte b in bytes)
            result = result * 23 + b;
        return result;
    }
}

Having said that, it just occurred to me that .NET 5 and 6 changed their Unicode support to use ICU instead of Win32, so who knows how "stable" my method is.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.