2012-03-01 14 views
5

Estoy tratando de escribir un método para convertir un objeto dado a una instancia de un tipo determinado. Empecé con esto:C# Ayúdame con un poco de genialidad de conversión genérica

private static T TryCast<T>(object o) 
{ 
    return (T) o; 
} 

Al entrar, lo sé que no va a funcionar, pero ilustra el concepto. Ahora, voy a comenzar a tener problemas cuando tengo tipos que no se lanzarán automáticamente, como string -> DateTime. Intenté usar Convert Class para tratar estos casos, pero acabo de obtener un error de tiempo de compilación en lugar de un error de tiempo de ejecución. El código siguiente obtiene el error de compilación "No se puede echar la expresión del tipo 'cadena' al tipo 'T'

private static T TryCast<T>(object o) 
{ 
    var typeName = typeof (T).FullName; 

    switch (typeName) 
    { 
     case "System.String": 
      return (T) Convert.ToString(o); 
     default: 
      return (T) o; 
    } 
} 

también estoy consciente de Convert.ChangeType(), pero me pregunto si va a manejar el borde casos que iba a manejar de otra manera en el interruptor de arriba, como la cadena declarado -.> Fecha y hora que yo normalmente sólo tiene que utilizar para Convert.ToDateTime

private static T TryCast<T>(object o) 
{ 
    return (T)Convert.ChangeType(o, typeof(T)); 
} 

Así que, ¿cuál es mi mejor opción si alguien puede dar? un enfoque viable, lo puedo tomar desde allí.

+0

OK, para dar un pequeño contexto, el uso inmediato de este método es asignar dinámicamente propiedades en una instancia de tipo T a partir de valores de columna en un objeto DataRow. Pasaría un Dictionary donde Key = nombre de propiedad en la instancia y Value = nombre de columna en DatRow. Ya tengo el reflejo escrito para obtener los PropertyInfos del tipo y establecer los valores de instancia. Este pequeño casting es mi última pieza del rompecabezas. Me gustaría que fuera lo más reutilizable posible, pero si limitar su alcance a mi ejemplo lo hace más fácil, que así sea. –

+0

Soy consciente de que el segundo ejemplo anterior DEBERÍA generar el error del compilador y por qué. Solo lo estoy usando para ilustrar el enfoque, gracias. No es tan nuevo: <) –

Respuesta

6

Convert.ChangeType debe manejar cajas de borde; delega a IConvertible.

Para responder a la pregunta, el compilador no sabe que T es string.
Por lo tanto, no le permite lanzar entre tipos no relacionados (al igual que no puede convertir Button en TextBox).

Puede evitar que echando a object primera:

return (T)(object)o.ToString(); 

Ahora, cada conversión individual es permitido por el compilador (es cualquiera de una conversión hacia arriba directo o un abatido directa), y usted sabe que el conjunto La cosa funcionará porque T es String.

+0

¿Por qué diablos no pensé en esto? Veamos lo que dicen los demás, pero esta podría ser la respuesta aceptada. –

Cuestiones relacionadas