Quiero convertir una cadena a un tipo genérico como into date, o longsobre la base del tipo de retorno genérico.
Básicamente, una función como Parse<T>(String)esa devuelve un elemento de tipo T.
Por ejemplo, si se pasó un int, la función debería hacerlo int.parseinternamente.
c#
string
parsing
type-conversion
Karim
fuente
fuente

IConvertable¿no debería restringir también elT, es decirT ChangeType<T>(this object obj) where T : IConvertable?objdebe ser asíIConvertible, pero no hay forma de especificarlo en tiempo de compilación.Bueno, parece que llegué demasiado tarde para responder en este hilo. Pero aquí está mi implementación:
Básicamente, he creado un método de extensión para la clase Object. Maneja todos los tipos, es decir, que aceptan valores NULL, clases y estructuras.
public static T ConvertTo<T>(this object value) { T returnValue; if (value is T variable) returnValue = variable; else try { //Handling Nullable types i.e, int?, double?, bool? .. etc if (Nullable.GetUnderlyingType(typeof(T)) != null) { TypeConverter conv = TypeDescriptor.GetConverter(typeof(T)); returnValue = (T) conv.ConvertFrom(value); } else { returnValue = (T) Convert.ChangeType(value, typeof(T)); } } catch (Exception) { returnValue = default(T); } return returnValue; }fuente
TypeDescriptorpara tipos que aceptan valores NULL yConvert.ChangeTypepara los que no aceptan valores NULL? Todo estetrybloque se puede reducir solo aTypeConverter2 líneas de código y funcionará tanto para nulos como para no nulos.System.Convert.ChangeTypeno se convierte a ningún tipo. Piense en lo siguiente:Estas conversiones son posibles con esta implementación de ChangeType .
fuente
versión más limpia de la respuesta de Pranay
public static T ConvertTo<T>(this object value) { if (value is T variable) return variable; try { //Handling Nullable types i.e, int?, double?, bool? .. etc if (Nullable.GetUnderlyingType(typeof(T)) != null) { return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value); } return (T)Convert.ChangeType(value, typeof(T)); } catch (Exception) { return default(T); } }fuente
Hay un par de convenciones en .NET para convertir objetos de un tipo a otro.
Pero estos métodos son mucho más lentos que los típicos
T.Parse(string), provocan el boxeo e involucran muchas asignaciones cada vez que desea convertir un solo valor.Para ValueString , elegí encontrar un método de análisis estático adecuado del tipo que usa reflexión, construir una expresión lambda llamándolo y almacenar en caché el delegado compilado para uso futuro (vea esta respuesta para un ejemplo).
También recurre a las formas que mencioné anteriormente si el tipo no tiene un método de análisis adecuado (consulte la sección de rendimiento en el archivo Léame).
var v = new ValueString("15"); // struct var i = v.As<int>(); // Calls int.Parse.fuente