---
title: "GetHashCode Made Easy - Muhammad Rehan Saeed"
description: "Implementing GetHashCode is hard work and little understood. Learn how to implement GetHashCode as quickly and as simply as possible."
canonical_url: "https://rehansaeed.com/gethashcode-made-easy/"
last_updated: "2019-06-12T00:00:00+00:00"
meta:
  author: "Muhammad Rehan Saeed"
  keywords: ".NET,Base Class Library,BCL,C#,GetHashCode"
  "og:description": "Implementing GetHashCode is hard work and little understood. Learn how to implement GetHashCode as quickly and as simply as possible."
  "og:image": "https://rehansaeed.com/_og/s/o_7f1407f5de4703eb.png"
  "og:image:alt": "GetHashCode Made Easy - Muhammad Rehan Saeed"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "GetHashCode Made Easy"
  "twitter:image": "https://rehansaeed.com/_og/s/o_7f1407f5de4703eb.png"
  "twitter:image:alt": "GetHashCode Made Easy - Muhammad Rehan Saeed"
---

> Index of every page on this site: [llms.txt](https://rehansaeed.com/llms.txt)

# [GetHashCode Made Easy](https://rehansaeed.com/gethashcode-made-easy/)

Posted 14 April 2014 and updated 12 June 2019 - **8 min read**

![Microsoft .NET](https://rehansaeed.com/_ipx/f_png&s_2560x1440/images/hero/Microsoft-.NET-1366x768.png)

Update (2021-10-22)

Updated after I discovered that there is a new Nuget package called `Microsoft.Bcl.HashCode` which allows you to use `System.HashCode` in frameworks older than `netstandard2.1`.

Update (2019-06-12)

I updated my HashCode implementation to cover a few more scenarios which I discuss below.

Update (2018-08-14)

I updated this article to talk about a new `HashCode` class included in .NET Core 2.1 and licensing information for my code since I've been asked repeatedly.

Implementing `GetHashCode` is hard work and little understood. If you take a look on MSDN or Stack Overflow for a few pointers, you'll see a plethora of examples with all kinds of little used C# operators and magic numbers with little explanation for developers (Especially the newbies) what they are for and why we need them. This, for a method which exists on the `Object` class and is the root of all that is good and wholesome in C# is surprising.

Before I continue, I recommend reading [Eric Lippert's blog post](http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) about the subject. He does not show any code, just goes into when and where we need to implement the `GetHashCode` method. Eric does a much better job than I could do but in short, `GetHashCode` is implemented wherever you implement the `Equals` method and ideally your class should be immutable.

Now down to the nitty gritty. How do we make implementing `GetHashCode` easy. Well, suppose we have the following class:

```cs
public sealed class SuperHero
{
    private readonly string name;
    private readonly int age;
    private readonly ReadOnlyCollection<string> powers;

    public SuperHero(string name, int age, IEnumerable<string> powers)
    {
        this.name = name;
        this.age = age;
        this.powers = new ReadOnlyCollection<string>(powers.ToList());
    }

    public int Age => this.age;

    public string Name => this.name;

    public ReadOnlyCollection<string> Powers => this.powers;

    public override bool Equals(object obj)
    {
        // ...
    }

    public override int GetHashCode()
    {
        // TODO
    }
}
```

In our example we have an immutable object with a variety of fields of different types, including a collection. One possible implementation of `GetHashCode` according to the highest rated [Stack Overflow post](http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode/263416#263416) (If modified to fit our example and deal with `null`'s) may be:

```cs
public override int GetHashCode()
{
    unchecked
    {
        int hashCode = 17;

        hashCode = (hashCode * 23) + (name == null ? 0 : this.name.GetHashCode());

        hashCode = (hashCode * 23) + this.age;

        foreach (string power in this.powers)
        {
            hashCode = (hashCode * 23) + (power == null ? 0 : power.GetHashCode());
        }

        return hashCode;
    }
}
```

I don't know about you but that code looks awfully unwieldy to me. For a start we've got two different magic numbers 17 and 23. Why? As it happens these are prime numbers and reduces the chance of getting collisions between hashes (Two un-equal objects are supposed to have different hash codes but sometimes this is not the case due to hash collisions that can occur).

We've also got the `unchecked` C# keyword which stops overflow checking to improve performance (That's not something you see every day). Bear in mind that the whole point of the `GetHashCode` method is to allow things like the `Dictionary` type to **quickly** retrieve objects.

I personally would not be able to remember how to do this each time I need to implement `GetHashCode` and it seems like you could very easily introduce bugs by making a typo. How about a helper class (Well actually a `struct` for better performance)?

```cs
/// <summary>
/// A hash code used to help with implementing <see cref="object.GetHashCode()"/>.
/// </summary>
public struct HashCode : IEquatable<HashCode>
{
    private const int EmptyCollectionPrimeNumber = 19;
    private readonly int value;

    /// <summary>
    /// Initializes a new instance of the <see cref="HashCode"/> struct.
    /// </summary>
    /// <param name="value">The value.</param>
    private HashCode(int value) => this.value = value;

    /// <summary>
    /// Performs an implicit conversion from <see cref="HashCode"/> to <see cref="int"/>.
    /// </summary>
    /// <param name="hashCode">The hash code.</param>
    /// <returns>The result of the conversion.</returns>
    public static implicit operator int(HashCode hashCode) => hashCode.value;

    /// <summary>
    /// Implements the operator ==.
    /// </summary>
    /// <param name="left">The left.</param>
    /// <param name="right">The right.</param>
    /// <returns>The result of the operator.</returns>
    public static bool operator ==(HashCode left, HashCode right) => left.Equals(right);

    /// <summary>
    /// Implements the operator !=.
    /// </summary>
    /// <param name="left">The left.</param>
    /// <param name="right">The right.</param>
    /// <returns>The result of the operator.</returns>
    public static bool operator !=(HashCode left, HashCode right) => !(left == right);

    /// <summary>
    /// Takes the hash code of the specified item.
    /// </summary>
    /// <typeparam name="T">The type of the item.</typeparam>
    /// <param name="item">The item.</param>
    /// <returns>The new hash code.</returns>
    public static HashCode Of<T>(T item) => new HashCode(GetHashCode(item));

    /// <summary>
    /// Takes the hash code of the specified items.
    /// </summary>
    /// <typeparam name="T">The type of the items.</typeparam>
    /// <param name="items">The collection.</param>
    /// <returns>The new hash code.</returns>
    public static HashCode OfEach<T>(IEnumerable<T> items) =>
        items == null ? new HashCode(0) : new HashCode(GetHashCode(items, 0));

    /// <summary>
    /// Adds the hash code of the specified item.
    /// </summary>
    /// <typeparam name="T">The type of the item.</typeparam>
    /// <param name="item">The item.</param>
    /// <returns>The new hash code.</returns>
    public HashCode And<T>(T item) =>
        new HashCode(CombineHashCodes(this.value, GetHashCode(item)));

    /// <summary>
    /// Adds the hash code of the specified items in the collection.
    /// </summary>
    /// <typeparam name="T">The type of the items.</typeparam>
    /// <param name="items">The collection.</param>
    /// <returns>The new hash code.</returns>
    public HashCode AndEach<T>(IEnumerable<T> items)
    {
        if (items == null)
        {
            return new HashCode(this.value);
        }

        return new HashCode(GetHashCode(items, this.value));
    }

    /// <inheritdoc />
    public bool Equals(HashCode other) => this.value.Equals(other.value);

    /// <inheritdoc />
    public override bool Equals(object obj)
    {
        if (obj is HashCode)
        {
            return this.Equals((HashCode)obj);
        }

        return false;
    }

    /// <summary>
    /// Throws <see cref="NotSupportedException" />.
    /// </summary>
    /// <returns>Does not return.</returns>
    /// <exception cref="NotSupportedException">Implicitly convert this struct to an <see cref="int" /> to get the hash code.</exception>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public override int GetHashCode() =>
        throw new NotSupportedException(
            "Implicitly convert this struct to an int to get the hash code.");

    private static int CombineHashCodes(int h1, int h2)
    {
        unchecked
        {
            // Code copied from System.Tuple so it must be the best way to combine hash codes or at least a good one.
            return ((h1 << 5) + h1) ^ h2;
        }
    }

    private static int GetHashCode<T>(T item) => item?.GetHashCode() ?? 0;

    private static int GetHashCode<T>(IEnumerable<T> items, int startHashCode)
    {
        var temp = startHashCode;

        var enumerator = items.GetEnumerator();
        if (enumerator.MoveNext())
        {
            temp = CombineHashCodes(temp, GetHashCode(enumerator.Current));

            while (enumerator.MoveNext())
            {
                temp = CombineHashCodes(temp, GetHashCode(enumerator.Current));
            }
        }
        else
        {
            temp = CombineHashCodes(temp, EmptyCollectionPrimeNumber);
        }

        return temp;
    }
}
```

The helper `struct` can be used in our `SuperHero` class like so:

```cs
public override int GetHashCode()
{
    return HashCode
        .Of(this.name)
        .And(this.age)
        .AndEach(this.powers);
}
```

Now isn't that pretty? All the nasty magic numbers and `unchecked` code has been hidden away. It is a very lightweight and simple `struct`, so although we create new instances of it, it's stored in the stack rather than the memory heap. What's more, is that is code is just as fast (I've timed it)! We're using generics so there is no boxing or unboxing going on. We're still using the `unchecked` keyword, so overflow checking is still disabled.

One interesting edge case is what to do when hashing a collection and you get either a `null` or empty collection. Should you use a zero to represent both scenarios (zero is usually used to represent a `null` value) or differentiate them somehow. I managed to get a response from Jon Skeet himself on Stack Overflow:

> if both states are valid, it seems perfectly reasonable to differentiate between them. (Someone carrying an empty box isn't the same as someone not carrying a box at all...)

This is why we use the prime number 19 (it could have been any prime number) to represent an empty collection. Whether this matters or not depends on your use case. If an empty collection means something different in your scenario, then we've got you covered. Generally speaking though, if you are exposing a collection property in your class you should consider making it a getter only and initializing it in the constructor, so that it is never `null` in the first place but here we're trying to cover all scenarios.

# .NET Core HashCode Link to this section

If you are using .NET Core 2.1, consider using the [System.HashCode](https://docs.microsoft.com/en-us/dotnet/api/system.hashcode?view=netcore-2.1) `struct` instead of my code. If your using an older framework you can also try the `Microsoft.Bcl.HashCode` NuGet package. There are two ways to use it:

## HashCode.Combine Link to this section

The `Combine` method can be used to create a hash code, given up to eight objects.

```cs
public override int GetHashCode() =>
    HashCode.Combine(object1, object2);
```

## HashCode.Add Link to this section

The Add method is similar to my code but it does not handle collections and is not fluent:

```cs
public override int GetHashCode()
{
    var hash = new HashCode();
    hash.Add(this.object1);
    hash.Add(this.object2);
    return hash.ToHashCode();
}
```

## Advantages and Disadvantages Link to this section

There are several advantages to using the .NET Core `HashCode`:

- It's part of the .NET Core base class library (BCL), so it's maintained and officially supported.
- It has good performance. I haven't written a benchmark against comparing my code to the .NET Core code. If you do, I'd be interested to hear the results.
- Like my code, it handles `null`'s automatically.

The disadvantages are:

- You have to be using .NET Core 2.1 or above.
- It does not handle collections, you have to write a for loop to handle that yourself. You could be clever and write a quick extension method to handle this scenario.
- It's not fluent, so you end up with slightly uglier code in my opinion. If you are a fan of C# 7 expression bodied members, then my fluent code lets you use them, while the .NET Core `HashCode.Add` method does not.

# License Link to this section

I have been asked repeatedly for licensing of my code above. Developers have been asking permission to use it in a Kerbal Space program plugin and even in the excellent [Chocolatey](https://chocolatey.org) project which has been totally unexpected for me because this is code I wrote years ago. It just goes to show how fundamental `GetHashCode` is. Please consider the code as MIT licensed, do good with it and be excellent to each other!

## Web Mentions

[What's this?](https://en.wikipedia.org/wiki/Webmention)

### 0 Linked

### 0 Replies

## GitHub Comments

### 24 Comments

[Comment on GitHub](https://github.com/RehanSaeed/rehansaeed.github.io/issues/78)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Nathan](https://camo.githubusercontent.com/f23b510c5bd9abf3b169d7eb542989720e1cfde88c6ba821712cf24625f3011f/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32353564393763643538626631383339646330613235386461353063626563393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/f23b510c5bd9abf3b169d7eb542989720e1cfde88c6ba821712cf24625f3011f/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32353564393763643538626631383339646330613235386461353063626563393f733d393626643d6d6d26723d67) **[Nathan](http://phetteplace.net/)** commented on **2014-06-13 12:52:08**

Very cool class!

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Savvas](https://camo.githubusercontent.com/05ad97290acd915837944dbd1bc7d1a44705bd35f3dfd6303c878edf7565acb1/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65353865306662353832363230383864346132333566636163333535623338623f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/05ad97290acd915837944dbd1bc7d1a44705bd35f3dfd6303c878edf7565acb1/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65353865306662353832363230383864346132333566636163333535623338623f733d393626643d6d6d26723d67) **Savvas** commented on **2014-07-30 13:23:01**

Very very nice! Thank you.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Trenton McFarlane](https://camo.githubusercontent.com/47f4048d96354725fa15b5767b1c8d071feb442e2f45021178c22c4a637ec967/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34356132326632383337663464393833623738666334316637346432393832613f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/47f4048d96354725fa15b5767b1c8d071feb442e2f45021178c22c4a637ec967/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34356132326632383337663464393833623738666334316637346432393832613f733d393626643d6d6d26723d67) **Trenton McFarlane** commented on **2016-07-27 02:18:55**

Very clean! Thank you! I've found but little help elsewhere on a clean implementation like this. Well done!

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Leonid Efremov](https://camo.githubusercontent.com/b473a644a55ecc416dccb985841f16db84873d402da8746b5085727cb11b91d3/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34386361663861663535623830653733316339353766353366383139323936323f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/b473a644a55ecc416dccb985841f16db84873d402da8746b5085727cb11b91d3/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34386361663861663535623830653733316339353766353366383139323936323f733d393626643d6d6d26723d67) **[Leonid Efremov](http://greenday.me/)** commented on **2017-09-06 11:51:07**

```
int hashCode = items.Select(x => GetHashCode(x)).Aggregate((x, y) => CombineHashCodes(x, y));
```

Will get Exception for empty array, maybe this is better to use:

```
var hashCode = items.Any() ? items.Select(GetHashCode).Aggregate(CombineHashCodes) : 0;
```

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2017-09-12 15:28:06**

> ```
> int hashCode = items.Select(x => GetHashCode(x)).Aggregate((x, y) => CombineHashCodes(x, y));
> ```
>
> Will get Exception for empty array, maybe this is better to use:
>
> ```
> var hashCode = items.Any() ? items.Select(GetHashCode).Aggregate(CombineHashCodes) : 0;
> ```

Thanks, I've updated the post.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Crispin](https://camo.githubusercontent.com/bf6140a10ae75572bf02f201f2111dcc360ad4547cf6ad06ab499324f3757918/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34643732363561363365386364633561643862313531323961663137643435383f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/bf6140a10ae75572bf02f201f2111dcc360ad4547cf6ad06ab499324f3757918/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34643732363561363365386364633561643862313531323961663137643435383f733d393626643d6d6d26723d67) **Crispin** commented on **2018-01-09 14:30:51**

> Thanks, I've updated the post.

Suggested correction is missing a null check on items. `Enumerable.Any` will null check argument and throw.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2018-01-23 11:51:52**

> Suggested correction is missing a null check on items. `Enumerable.Any` will null check argument and throw.

Added your suggestion. Thanks.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Union](https://camo.githubusercontent.com/d7f40c21d6f174d224803c670843e47c4b643ee5f84de9e8210be4d637b9172f/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f30633466356633386437393236306130316332356464656636353830623166333f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/d7f40c21d6f174d224803c670843e47c4b643ee5f84de9e8210be4d637b9172f/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f30633466356633386437393236306130316332356464656636353830623166333f733d393626643d6d6d26723d67) **Union** commented on **2018-03-24 01:45:03**

Very cool! You should make this a nuget package

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Simeon](https://camo.githubusercontent.com/82f2a0c5eb4948a3a088b493862a923cbc1165092c4a9d50d76685f61a305e0d/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f35653035653835383337323437613463373932396464613765396564303032623f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/82f2a0c5eb4948a3a088b493862a923cbc1165092c4a9d50d76685f61a305e0d/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f35653035653835383337323437613463373932396464613765396564303032623f733d393626643d6d6d26723d67) **Simeon** commented on **2018-08-14 15:20:18**

This struct is so great that it should go straight into the .NET Framework! Thank You, Rehan, for sharing it with us! However, I could not find any license information about it. Could you, please, let us know how we are allowed to use it.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2018-08-14 16:12:53**

> This struct is so great that it should go straight into the .NET Framework! Thank You, Rehan, for sharing it with us! However, I could not find any license information about it. Could you, please, let us know how we are allowed to use it.

Thanks! You are in fact the third person to ask about licensing. I have updated the blog post with information about a new helper available in .NET Core and also licensing information.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Matt Whitfield](https://camo.githubusercontent.com/816d4b143415d206aaef038d6c11cc578487b3b18a20fbc60dd2187941e3886a/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f61353530656562653963313439313134613166646536663433663061653837363f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/816d4b143415d206aaef038d6c11cc578487b3b18a20fbc60dd2187941e3886a/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f61353530656562653963313439313134613166646536663433663061653837363f733d393626643d6d6d26723d67) **Matt Whitfield** commented on **2018-08-16 09:30:28**

Pretty sure this is wrong: 'Two equal objects are supposed to have the same hash code but sometimes this is not the case due to some maths that I'm not going to go into'. I think you mean 'Two objects that are not equal are supposed to have different hash codes'. Because having two objects that are equal and do not have the same hash code breaks equality.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2018-08-16 11:25:58**

> Pretty sure this is wrong: 'Two equal objects are supposed to have the same hash code but sometimes this is not the case due to some maths that I'm not going to go into'. I think you mean 'Two objects that are not equal are supposed to have different hash codes'. Because having two objects that are equal and do not have the same hash code breaks equality.

Sometimes there are hash collisions where objects which are not equal to each other produce the same hash.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Brandon](https://camo.githubusercontent.com/e55e8b8ce4a9c51dc6211dc3a5222dc9341621243d6d8d4b773c4228209597ac/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f64393361636135643761663139366136333639663237343330383537366338393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/e55e8b8ce4a9c51dc6211dc3a5222dc9341621243d6d8d4b773c4228209597ac/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f64393361636135643761663139366136333639663237343330383537366338393f733d393626643d6d6d26723d67) **Brandon** commented on **2018-08-16 12:32:08**

> Sometimes there are hash collisions where objects which are not equal to each other produce the same hash.

Hi, great post and thanks for it, for clarification I thought Matt was indicating a possible need to update the article. I also think "Two equal objects are supposed to have the same hash code but sometimes this is not the case due to some maths that I'm not going to go into" is stated incorrectly. Two equal objects do indeed have the same hash. We are assuming you meant "Two un-equal objects are supposed to have different hash codes but sometimes this is not the case, a hash collision, due to some maths that I'm not going to go into". By definition equal objects can't have unequal hashes, correct?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Matt Whitfield](https://camo.githubusercontent.com/7b7d704ce3af7fa18aefea20738fca14517c423c4c92ec1925b2034faa3040ce/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f66353339363633356338386536666537653933626533333630333031633266343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/7b7d704ce3af7fa18aefea20738fca14517c423c4c92ec1925b2034faa3040ce/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f66353339363633356338386536666537653933626533333630333031633266343f733d393626643d6d6d26723d67) **Matt Whitfield** commented on **2018-08-16 13:27:04**

> Sometimes there are hash collisions where objects which are not equal to each other produce the same hash.

So might be an idea to update the phrase that's wrong above then?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2018-08-16 14:55:21**

> So might be an idea to update the phrase that's wrong above then?

I re-read your comment and yes, you are totally right. Updated, thank you!

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Nadav](https://camo.githubusercontent.com/9222113868de708a9dc91360acd77a531a7ab2b17a0cd5c0dbb22a431aa5b8ae/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f62373263303138333435373234656534653336623163666130326233643733323f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/9222113868de708a9dc91360acd77a531a7ab2b17a0cd5c0dbb22a431aa5b8ae/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f62373263303138333435373234656534653336623163666130326233643733323f733d393626643d6d6d26723d67) **Nadav** commented on **2018-12-11 15:01:56**

Shouldn't:

```
public HashCode AndEach(IEnumerable items)
```

Be:

```
public HashCode AndEach(IEnumerable items)
```

Also, if you want the code to be as fast as possible, then you should not use Linq, using

```
var temp = this.value;
foreach (T item in items)
{
    temp = CombineHashCodes(temp, GetHashCode(item));
}
return new HashCode(temp);
```

Is much faster....

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020 (edited 12 May 2020)

[![Oliver](https://camo.githubusercontent.com/f2e6937475e029ddd8888e8614be47c92736ce60ad3c8b785f66525ed74267e7/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34616538666262386637373432663364343631353134656239323165376238393f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/f2e6937475e029ddd8888e8614be47c92736ce60ad3c8b785f66525ed74267e7/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f34616538666262386637373432663364343631353134656239323165376238393f733d393626643d6d6d26723d67) **Oliver** commented on **2018-12-14 09:46:36**

Just another idea (I used in my implementation): `HashCode` has to be fast and collisions for different objects are allowed (than `Equals()` has to be called). So for collection it is not always wise to iterate over all elements (maybe there are millions in there) and maybe it is just enough to consider the first n-elements for generating the hash code. So for this purpose it would be great to enhance the `.AndEach()` call to take a second optional number parameter `AndEach(IEnumerable items, int count =10)` which will simply be added to the LINQ statement as `items.Take(count).Select(GetHashCode)`. Within the usage you can then provide a meaningful number for your use-case. This update maybe changes existing implementations. To avoid this, the optional parameter could also be initialized with `int.MaxValue` to provide the current behaviour.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2018-12-14 11:40:03**

> Shouldn't:
>
> ```
> public HashCode AndEach(IEnumerable items)
> ```
>
> Be:
>
> ```
> public HashCode AndEach(IEnumerable items)
> ```
>
> Also, if you want the code to be as fast as possible, then you should not use Linq, using
>
> ```
> var temp = this.value;
> foreach (T item in items)
> {
>     temp = CombineHashCodes(temp, GetHashCode(item));
> }
> return new HashCode(temp);
> ```
>
> Is much faster....

Good point about not using Linq.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020 (edited 12 May 2020)

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2018-12-14 11:41:37**

> Just another idea (I used in my implementation): `HashCode` has to be fast and collisions for different objects are allowed (than `Equals()` has to be called). So for collection it is not always wise to iterate over all elements (maybe there are millions in there) and maybe it is just enough to consider the first n-elements for generating the hash code. So for this purpose it would be great to enhance the `.AndEach()` call to take a second optional number parameter `AndEach(IEnumerable items, int count =10)` which will simply be added to the LINQ statement as `items.Take(count).Select(GetHashCode)`. Within the usage you can then provide a meaningful number for your use-case. This update maybe changes existing implementations. To avoid this, the optional parameter could also be initialized with `int.MaxValue` to provide the current behaviour.

That's an interesting idea. Not sure how often this use cases pops up.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Laksh](https://camo.githubusercontent.com/1f1773638edb400870e5d82cbe58e885fd030ce2388bcfc6fbafefb595cf7fbc/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65356563343664393566363531313630653333386434306435663834326633633f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/1f1773638edb400870e5d82cbe58e885fd030ce2388bcfc6fbafefb595cf7fbc/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65356563343664393566363531313630653333386434306435663834326633633f733d393626643d6d6d26723d67) **Laksh** commented on **2019-07-11 21:46:51**

Are any of the hash code methods you mentioned are deterministic? The `HashCode` class from .NET Core is not deterministic.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2019-07-16 10:14:47**

> Are any of the hash code methods you mentioned are deterministic? The `HashCode` class from .NET Core is not deterministic.

`Object.GetHashCode` returns different values every time an application is restarted. So it is not strictly deterministic and you should not rely on it being so. It sounds like you want to use one of the other hash algorithms in the cryptographic namespace which are deterministic.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Nawfal](https://camo.githubusercontent.com/d1fbf0df29c9bf56237be7c3147dad4a170dfdff3140893567260d23ebbb9637/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f61363065313665663861316631383136343838326266626337643161316561313f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/d1fbf0df29c9bf56237be7c3147dad4a170dfdff3140893567260d23ebbb9637/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f61363065313665663861316631383136343838326266626337643161316561313f733d393626643d6d6d26723d67) **Nawfal** commented on **2020-05-06 20:36:52**

Hi Rehan, is your `HashCode` implementation published as a nuget package?

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2020-05-07 12:48:30**

> Hi Rehan, is your `HashCode` implementation published as a nuget package?

No. Maybe I'll add it though. Seems strange to do so for one simple class.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Nawfal](https://camo.githubusercontent.com/d1fbf0df29c9bf56237be7c3147dad4a170dfdff3140893567260d23ebbb9637/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f61363065313665663861316631383136343838326266626337643161316561313f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/d1fbf0df29c9bf56237be7c3147dad4a170dfdff3140893567260d23ebbb9637/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f61363065313665663861316631383136343838326266626337643161316561313f733d393626643d6d6d26723d67) **Nawfal** commented on **2020-05-07 19:34:39**

> No. Maybe I'll add it though. Seems strange to do so for one simple class.

Rehan, alright. Its not really required. I could just copy the class. Asking just in case..

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://rehansaeed.com/#website","@type":"WebSite","description":"Software Developer at Microsoft, YouTuber, Open Source Contributor and Blogger","inLanguage":"en-GB","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/","author":{"@id":"https://rehansaeed.com/#identity"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://rehansaeed.com/?search={search_term_string}"},"query-input":"required name=search_term_string"}],"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/gethashcode-made-easy/#webpage","@type":"WebPage","dateModified":"2019-06-12T00:00:00+00:00","datePublished":"2014-04-14T00:00:00+00:00","description":"Implementing GetHashCode is hard work and little understood. Learn how to implement GetHashCode as quickly and as simply as possible.","name":"GetHashCode Made Easy","url":"https://rehansaeed.com/gethashcode-made-easy/","breadcrumb":{"@id":"https://rehansaeed.com/gethashcode-made-easy/#breadcrumb"},"isPartOf":{"@id":"https://rehansaeed.com/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://rehansaeed.com/gethashcode-made-easy/"]}]},{"@id":"https://rehansaeed.com/#identity","@type":"Person","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/about/","image":{"@id":"https://rehansaeed.com/#/schema/image/1"},"sameAs":["https://github.com/RehanSaeed","https://www.linkedin.com/in/muhammad-rehan-saeed","https://stackoverflow.com/users/1212017/muhammad-rehan-saeed","https://www.youtube.com/c/MuhammadRehanSaeed","https://www.twitch.tv/rehansaeeduk"]},{"@id":"https://rehansaeed.com/#publisher","@type":"Organization","logo":"https://rehansaeed.com/images/schema/Publisher-600x60.png","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com"},{"@id":"https://rehansaeed.com/gethashcode-made-easy/#article","@type":"Article","dateModified":"2019-06-12T00:00:00+00:00","datePublished":"2014-04-14T00:00:00+00:00","description":"Implementing GetHashCode is hard work and little understood. Learn how to implement GetHashCode as quickly and as simply as possible.","headline":"GetHashCode Made Easy","inLanguage":"en-GB","url":"https://rehansaeed.com/gethashcode-made-easy/","author":{"@id":"https://rehansaeed.com/#identity"},"image":[{"@type":"ImageObject","url":"https://rehansaeed.com/images/hero/Microsoft-.NET-1366x768.png","caption":"Microsoft .NET","width":"1366","height":"768"}],"isPartOf":{"@id":"https://rehansaeed.com/gethashcode-made-easy/#webpage"},"keywords":[".NET","Base Class Library","BCL","C#","GetHashCode"],"mainEntityOfPage":{"@id":"https://rehansaeed.com/gethashcode-made-easy/#webpage"},"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/gethashcode-made-easy/#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://rehansaeed.com/","position":1},{"@type":"ListItem","name":"GetHashCode Made Easy","item":"https://rehansaeed.com/gethashcode-made-easy/","position":2}]},{"@id":"https://rehansaeed.com/#/schema/image/1","@type":"ImageObject","contentUrl":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png","inLanguage":"en-GB","url":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png"}]}
```

## Sitemap

See the full [sitemap](https://rehansaeed.com/sitemap.md) for all pages.
