I'm thinking this could be a convenient dictionary:
var myDict = new Dictionary<(int, int), bool>();
What would the hashes look like?
What would the equivalent key type (struct) look like?
I'm thinking this could be a convenient dictionary:
var myDict = new Dictionary<(int, int), bool>();
What would the hashes look like?
What would the equivalent key type (struct) look like?
Yes, that's fine. The ValueTuple<...>
family is a well-defined set of regular structs with the correct equality and hash-code behaviour to work as dictionary keys. There is a slight caveat in that they are mutable rather than immutable, but that doesn't really impact them in this context thanks to copy semantics (which means: you can't change the key after it has been added, as you're only changing a different copy of the key; this is very different to the problem with mutable classes as keys). You can see the code here.
(int,int)
uses public struct ValueTuple<T1, T2>
from that linked file, specifically as ValueTuple<int,int>
–
Alkalimeter Tuple
immutable, but a class, then they made ValueTuple
a struct, but made it mutable. –
Capability Tuple<...>
family would have been incredibly dangerous; a mutable struct ValueTuple<...>
family is much much safer, and enables a few scenarios without causing any key equality problems. I might have preferred it as immutable (I love me some readonly struct
), but... meh, in this case it makes sense. –
Alkalimeter Tuple
being mutable, but to me it didn't make sense that it was a class in the first place. I really like the way .NET is going with reducing allocations (e.g. Span<T>
), I would have just preferred both of them immutable as you wrote. –
Capability Being a value type, the hash for ValueTuple
follows the default implementation, which is based on the values of the members:
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. In other words, value types whose fields have equal values have equal hash codes.
Tuples are mutable, but because they are copied by value, you can use them safely as dictionary keys. A problem might be if you use a variable of a tuple type, use this variable in Dictionary.Add
, then modify this variable and try to access the associated value from the dictionary using the same variable as a key. In this case you will not find it in the dictionary.
The equivalent structure would be like:
MyStruct : struct
{
public int A;
public int B;
}
IEquatable<MyStruct>
and have custom GetHashCode()
/Equals(object)
/Equals(MyStruct)
implementations - yes it'll work without them, but it'll cause boxing in all the "constrained call" checks and the EqualityComparer<T>.Default
implementation - which changes the behaviour quite a bit –
Alkalimeter GetHashCode()
, IEquatable<>
etc. if anyone knows. –
Murillo © 2022 - 2024 — McMap. All rights reserved.
ValueTuple
is a struct, on the other hand, no allocations, no GC, simple equality check. – CapabilityValueTuple
doesn't fit properly. – Murillo