Firstly, I've asked this question elsewhere, but meta.stackoverflow.com seems to think that asking the same questions elsewhere is fine, so here goes. I'll update both if/when I get an answer.
I'm doing a lot of conversion between simple types and I wanted to handle it as nicely as possible. What I thought would be nice would be to be able to do something like this:
var converter = GetMySingletonConverterRegistryPlease();
var somePoint = GetMeSomePointFromSomewhereThanks();
converter.Register<Point, List<int>>(
point => new List<int>{ point.X, point.Y }
);
var someInts = somePoint.To<List<int>>();
So, I came up with the following. Which I'm not at all happy with and would like some advice on (I'll enumerate why I don't like it after the code snippet)
public sealed class TypeConverterRegistry : TypeConverterRegistryBase {
public static readonly TypeConverterRegistry Instance = new
TypeConverterRegistry();
static TypeConverterRegistry() {}
TypeConverterRegistry() {}
}
public abstract class TypeConverterRegistryBase {
private readonly Dictionary<object, Delegate> _converters = new
Dictionary<object, Delegate>();
public void Register<TFrom, TTo>( Func<TFrom, TTo> converter ) {
var key = new { From = typeof( TFrom ), To = typeof( TTo ) };
_converters[ key ] = converter;
}
public TTo ConvertTo<TTo>( object from ) {
var key = new { From = from.GetType(), To = typeof( TTo ) };
if( !_converters.ContainsKey( key ) )
throw new KeyNotFoundException(
"No converter has been registered that takes a " + key.From +
" and returns a " + key.To );
var converter = _converters[ key ];
return (TTo) converter.DynamicInvoke( from );
}
}
public static class Extensions {
public static TTo To<TTo>( this object value ) {
return TypeConverterRegistry.Instance.ConvertTo<TTo>( value );
}
}
I don't like what I've done here, because it's not strongly typed/constrained, it's easy to accidentally misuse it and get a runtime exception, I'm using object as a catch all, and I also have a bad feeling about the way I'm calling DynamicInvoke and boxing the result. You guys will no doubt see even more problems than that! Also I feel bad about making an extension method on object.
What I do like is the resulting syntax!
So I'd really appreciate any advice, even if it's just a nudge in the right direction.
Or reassurance that it's not such a bad way to do it after all :P