I have a cache that I implement using a ConcurrentDictionary, The data that I need to keep depends on 5 parameters. So the Method to get it from the cache is: (I show only 3 parameters here for simplicity, and I changed the data type to represent CarData for clearity)
public CarData GetCarData(string carModel, string engineType, int year);
I wonder what type of key will be better to use in my ConcurrentDictionary, I can do it like this:
var carCache = new ConcurrentDictionary<string, CarData>();
// check for car key
bool exists = carCache.ContainsKey(string.Format("{0}_{1}_{2}", carModel, engineType, year);
Or like this:
var carCache = new ConcurrentDictionary<Tuple<string, string, int>, CarData>();
// check for car key
bool exists = carCache.ContainsKey(new Tuple(carModel, engineType, year));
I don't use these parameters together any other place, so there is no justification to create a class just to keep them together.
I want to know which approach is a better in terms of performance and maintainability.
You could create a class (doesn't matter that its only used here) that overrides GetHashCode and Equals:
Thanks theDmi (and others) for improvements...
If you don't override those, ContainsKey does a reference equals.
Note: the
Tuple
class does have its own equality functions that would basically do the same as above. Using a bespoke class makes it clear that is what is intended to happen - and is therefore better for maintainability. It also has the advantage that you can name the properties so it is clearNote 2: the class is immutable as dictionary keys need to be to avoid potential bugs with hashcodes changing after the object is added to the dictionary See here
GetHashCode taken from here