24

.NET Standard 2.1 / .NET Core 3 introduce System.HashCode to quickly combine fields and values to a hash code without having to care about the underlying implementation.

However, it only provides Combine method overloads for up to 8 values. What do I do if I have a class with 9 values (3x3 matrix) or even 16 values (4x4 matrix)?

Should I be simply adding up two Combine calls, passing as many values as possible in each?

public override int GetHashCode()
    => HashCode.Combine(M11, M12, M13, M21, M22, M23, M31, M32) + HashCode.Combine(M33);

Looking at the source, I cannot completely argue if this may have implications I don't know of.

Ray
  • 7,940
  • 7
  • 58
  • 90

1 Answers1

43

As stated in the System.HashCode documentation you actually linked yourself, simply adding up hash codes created by successive Combine calls is not the solution.

It is correct that the static Combine methods only allow up to 8 values, but these seem to be only comfort methods. To combine more than 8 values, you have to resort to instantiating HashCode and using it like this:

public override int GetHashCode()
{
    HashCode hash = new();
    hash.Add(M11);
    hash.Add(M12);
    hash.Add(M13);
    hash.Add(M21);
    hash.Add(M22);
    hash.Add(M23);
    hash.Add(M31);
    hash.Add(M32);
    hash.Add(M33);
    return hash.ToHashCode();
}

It does make me wonder why there is no HashCode constructor accepting a params object[] values so you could do all that in one line, but there are probably reasons I didn't think of this quickly.

Still a lot better than doing all the inner workings yourself! :-)

Ray
  • 7,940
  • 7
  • 58
  • 90
  • 7
    It might have something to do with allocating an array, which *can* be a performance drag. Since .NET Core is more performance oriented, I would think that that's the reason. – germi Dec 17 '19 at 13:24
  • 5
    Not only array allocation but also boxing of every value type. Horribly inefficient. – freakish Sep 23 '21 at 07:52
  • It neither does boxing nor array allocation – Vlad Jul 05 '22 at 06:47
  • @Vlad Why not? Surely it has to do with performance considerations.. – niproblema Aug 28 '22 at 06:12
  • I meant that using `HashCode.Add` method doesn't lead to boxing or array allocation – Vlad Aug 28 '22 at 10:23
  • 2
    @Vlad I think the concerns about boxing and array allocation were made about a constructor accepting a `params object[] values` which absence I mentioned in my answer, not the calls to `HashCode.Add`. – Ray Aug 28 '22 at 13:15