How to use System.HashCode.Combine with more than 8 values?
Asked Answered
S

1

32

.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 simply add together the results of 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.

Subtrahend answered 17/12, 2019 at 13:18 Comment(0)
S
59

As stated in the System.HashCode documentation, adding together hashes returned by successive HashCode.Combine calls is NOT the solution.

While the static HashCode.Combine method overloads only allow up to 8 values, these are just convenience methods - to combine more, instantiate the HashCode class itself and use it as follows:

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. (S. the comments why such an overload does not exist.)

Subtrahend answered 17/12, 2019 at 13:18 Comment(6)
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.Stavro
Not only array allocation but also boxing of every value type. Horribly inefficient.Kordofan
It neither does boxing nor array allocationAuden
@Auden Why not? Surely it has to do with performance considerations..Saxton
I meant that using HashCode.Add method doesn't lead to boxing or array allocationAuden
@Auden 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.Subtrahend

© 2022 - 2024 — McMap. All rights reserved.