In the solution I have worked out to this question => General type conversion without risking Exceptions (See the edit at the bottom of the question), I need to cache a method for converting between two types.
So, given Type1 and Type2 I need to retrieve a method.
In the answer to this question => What is the best C# collection with two keys and an object? it is recommended to use a dictionary of dictionaries. This is similar to what I am doing.
But I dont like it. It doesnt flow logically with what the collection is meant to represent. Also to retrieve a value I have to do :
if ( !_Types.ContainsKey ( s.GetType () ) )
{
type1Cache = new Dictionary<Type, ConversionCache> ();
_Types.Add ( s.GetType (), type1Cache );
}
else
{
type1Cache = _Types[s.GetType ()];
}
if ( !type1Cache.ContainsKey ( value.GetType () ) )
{
// We havent converted this type before, so create a new conversion
type2Cache = new ConversionCache ( s.GetType (), value.GetType () );
// Add to the cache
type1Cache.Add ( value.GetType (), type2Cache );
}
else
{
type2Cache = type1Cache[value.GetType ()];
}
which is a bit long winded.
I just want to do something like
if ( !_Types.ContainsKey ( s.GetType (), value.GetType() ) )
{
cache = new ConversionCache ( s.GetType (), value.GetType () );
_Types.Add ( s.GetType (), value.GetType(), cache);
}
else
{
cache = _Types[s.GetType (), value.GetType()];
}
One solution would be to concatenate the string values of the types. Something like :
if ( !_Types.ContainsKey ( s.GetType ().ToString() + ":" + value.GetType().ToString() ) )
{
cache = new ConversionCache ( s.GetType (), value.GetType () );
_Types.Add ( s.GetType ().ToString() + ":" + value.GetType().ToString(), cache);
}
else
{
cache = _Types[s.GetType ().ToString() + ":" + value.GetType().ToString()];
}
I know it would work in this instance because there is a one-to-one between a type and its string representation.
But that smells pretty bad, and wouldnt work in other situations.
Is there a better way to do this?
The way you are doing it is fine. If you want a better “smelling” system all you would need is a helper function that takes two inputs (or types) and return a unique string. Then the implementation details of generating the key (in this case concatenating them with a “:” separator) are hidden.
Seems like a little over-engineering to me. I don’t believe there is much of a chance you will need to change this key generation method and you are not trying to make a generic class. Clearly you would need to do it with a generic class.