Manteniendo la idea de un convertidor para omitir un bloque de interruptores, puede utilizar el concepto de Duck Typing. Básicamente, desea convertir una cadena en X, por lo que crea un método que llamará X.TryParse (cadena, fuera X x) si X tiene TryParse en él, de lo contrario no se molestará (o supongo que podría lanzar un error). ¿Cómo harías esto? Reflexión y genéricos
Básicamente, tendría un método que tomaría un tipo y usaría la reflexión para ver si tiene TryParse en él. Si encuentra un método así, llámelo y devuelva lo que TryParse logró obtener. Esto funciona bien con casi cualquier tipo de valor, como Decimal o DateTime.
public static class ConvertFromString
{
public static T? ConvertTo<T>(this String numberToConvert) where T : struct
{
T? returnValue = null;
MethodInfo neededInfo = GetCorrectMethodInfo(typeof(T));
if (neededInfo != null && !numberToConvert.IsNullOrEmpty())
{
T output = default(T);
object[] paramsArray = new object[2] { numberToConvert, output };
returnValue = new T();
object returnedValue = neededInfo.Invoke(returnValue.Value, paramsArray);
if (returnedValue is Boolean && (Boolean)returnedValue)
{
returnValue = (T)paramsArray[1];
}
else
{
returnValue = null;
}
}
return returnValue;
}
}
Dónde GetCorrectMethodInfo sería algo como esto:
private static MethodInfo GetCorrectMethodInfo(Type typeToCheck)
{
MethodInfo returnValue = someCache.Get(typeToCheck.FullName);
if(returnValue == null)
{
Type[] paramTypes = new Type[2] { typeof(string), typeToCheck.MakeByRefType() };
returnValue = typeToCheck.GetMethod("TryParse", paramTypes);
if (returnValue != null)
{
CurrentCache.Add(typeToCheck.FullName, returnValue);
}
}
return returnValue;
}
Y uso sería:
decimal? converted = someString.ConvertTo<decimal>();
Odio enchufar a mí mismo, pero tengo esta totalmente explicado aquí:
GetCorrectMethodInfo
Rest of It
El otro beneficio adicional es que el método TryParse devuelve una variable booleana, por lo que es fácil codificar sus escenarios de éxito y falla al analizar el número. –
pero si solo te importa si es un número entero o no, TryParse tiene la ventaja de que debes declarar una variable para el parámetro out –