Alxandr
Alxandr

Reputation: 12423

Using a combination of two fields as key in a dictionary

I need to store a c# dict where I can store members based on a IntPtr and a enum (castable to int if that helps). In other words, if I get the same match of IntPtr and the enum (named sp_playlist_type) I need to be able to get the same result out, but only then (that's also important). I've figured I'd make a struct containing the two, and override GetHashCode(), but then I'd need a hashing-algorithm that doesn't create duplicates for the two numbers, and generates the same result every time the same two numbers are present.

Upvotes: 3

Views: 1927

Answers (4)

to StackOverflow
to StackOverflow

Reputation: 124696

It's not strictly necessary to override GetHashCode, since as others mention there is no requirement for it to be unique.

However it may be desirable to override Equals for your struct for performance reasons, as described in MSDN.

In which case it is recommended to override GetHashCode. Probably in this case an XOR of the IntPtr and the enum (the LS 32-bits of the IntPtr on a 64-bit system).

Upvotes: 0

Borja
Borja

Reputation: 2198

An easy way to do it is use an string as key, you combine in this string both values. For example:

private string GetKey(IntPrt prt, sp_playlist_type playlist_type)
{
    return string.format("{0}#{1}", prt, type)
}

To use it, you use something like:

mydic.add(GetKey(ptr, playlist_type), myvalue);

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564383

then I'd need a hashing-algorithm that doesn't create duplicates for the two numbers

This actually is not true. You need to override GetHashCode(), but it can have collisions. You want to minimize collisions in your hash codes, not eliminate them.

This is actually fairly easy to do. A common option is to just use the XOR of the hash codes of both members of the struct, or something similar to that.

Upvotes: 7

James Michael Hare
James Michael Hare

Reputation: 38397

I think based on the way Tuple's GetHashCode and Equality is alredy created, you could have:

Dictionary<Tuple<IntPtr, YourEnum>, YourResultType>

Provided you are on .NET 4.0 of course.

Upvotes: 6

Related Questions