Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

.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.

like image 574
Ray Avatar asked Dec 17 '19 13:12

Ray


People also ask

What does Hashcode combine do?

Combines two values into a hash code.

How does GetHashCode work in C#?

GetHashCode. In other words, two objects for which the ReferenceEquals method returns true have identical hash codes. If value types do not override GetHashCode, the ValueType. GetHashCode method of the base class uses reflection to compute the hash code based on the values of the type's fields.

Is Hashcode always the same?

No, the value can change between computers and base system versions. You should only depend on it to be constant during a given program run.


1 Answers

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 HashCode();
    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! :-)

like image 166
Ray Avatar answered Oct 02 '22 20:10

Ray