tipos que long ejemplos datos conversion c# .net generics extension-methods type-conversion

que - tipos de datos en c# pdf



Convierte cadena a tipo anulable(int, double, etc...) (15)

¿Qué tal esto?

double? amount = string.IsNullOrEmpty(strAmount) ? (double?)null : Convert.ToDouble(strAmount);

Por supuesto, esto no tiene en cuenta el error de conversión.

Estoy intentando hacer una conversión de datos. Desafortunadamente, gran parte de la información está en cadenas, donde debería ser int o doble, etc.

Entonces, lo que tengo es algo así como:

double? amount = Convert.ToDouble(strAmount);

El problema con este enfoque es si strAmount está vacío, si está vacío, quiero que importe para que sea nulo, así que cuando lo agregue a la base de datos, la columna será nula. Así que terminé escribiendo esto:

double? amount = null; if(strAmount.Trim().Length>0) { amount = Convert.ToDouble(strAmount); }

Ahora esto funciona bien, pero ahora tengo cinco líneas de código en lugar de una. Esto hace que las cosas sean un poco más difíciles de leer, especialmente cuando tengo una gran cantidad de columnas para convertir.

Pensé que usaría una extensión para la clase de cadenas y genéricos para pasar el tipo, esto es porque podría ser un doble, un int o un largo. Así que probé esto:

public static class GenericExtension { public static Nullable<T> ConvertToNullable<T>(this string s, T type) where T: struct { if (s.Trim().Length > 0) { return (Nullable<T>)s; } return null; } }

Pero me aparece el error: ¿No se puede convertir el tipo ''cadena'' en ''T''?

¿Hay alguna forma de evitar esto? No estoy muy familiarizado con la creación de métodos con genéricos.


Agreguemos una solución más similar a la pila. Este también analiza enums, y se ve bien. Muy seguro.

/// <summary> /// <para>More convenient than using T.TryParse(string, out T). /// Works with primitive types, structs, and enums. /// Tries to parse the string to an instance of the type specified. /// If the input cannot be parsed, null will be returned. /// </para> /// <para> /// If the value of the caller is null, null will be returned. /// So if you have "string s = null;" and then you try "s.ToNullable...", /// null will be returned. No null exception will be thrown. /// </para> /// <author>Contributed by Taylor Love (Pangamma)</author> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="p_self"></param> /// <returns></returns> public static T? ToNullable<T>(this string p_self) where T : struct { if (!string.IsNullOrEmpty(p_self)) { var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)); if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self); if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;} } return null; }

https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs


Aquí hay algo basado en la respuesta aceptada. Eliminé el try / catch para asegurarme de que no se traten todas las excepciones y no se solucionen. También se aseguró de que la variable de retorno (en respuesta aceptada) nunca se inicialice dos veces por nada.

public static Nullable<T> ToNullable<T>(this string s) where T: struct { if (!string.IsNullOrWhiteSpace(s)) { TypeConverter conv = TypeDescriptor.GetConverter(typeof(T)); return (T)conv.ConvertFrom(s); } return default(Nullable<T>); }


Dale una oportunidad ...

public delegate bool TryParseDelegate<T>(string data, out T output); public static T? ToNullablePrimitive<T>(this string data, TryParseDelegate<T> func) where T:struct { string.IsNullOrEmpty(data) return null; T output; if (func(data, out output)) { return (T?)output; } return null; }

Entonces llámalo así ...

void doStuff() { string foo = "1.0"; double? myDouble = foo.ToNullablePrimitive<double>(double.TryParse); foo = "1"; int? myInt = foo.ToNullablePrimitive<int>(int.TryParse); foo = "haha"; int? myInt2 = foo.ToNullablePrimitive<int>(int.TryParse); }


Es posible que desee intentar:

TypeConverter conv = TypeDescriptor.GetConverter(typeof(int)); conv.ConvertFrom(mystring);

hacer su propia comprobación nula y devolver int? si necesario. También querrás envolverlo en una try {}


Escribí este convertidor de tipo genérico. Funciona con valores Nullable y estándar, convirtiendo entre todos los tipos convertibles, no solo en cadenas. Maneja todo tipo de escenarios que usted esperaría (valores predeterminados, valores nulos, otros valores, etc.)

He estado usando esto durante aproximadamente un año en docenas de programas de producción, por lo que debería ser bastante sólido.

public static T To<T>(this IConvertible obj) { Type t = typeof(T); if (t.IsGenericType && (t.GetGenericTypeDefinition() == typeof(Nullable<>))) { if (obj == null) { return (T)(object)null; } else { return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(t)); } } else { return (T)Convert.ChangeType(obj, t); } } public static T ToOrDefault<T> (this IConvertible obj) { try { return To<T>(obj); } catch { return default(T); } } public static bool ToOrDefault<T> (this IConvertible obj, out T newObj) { try { newObj = To<T>(obj); return true; } catch { newObj = default(T); return false; } } public static T ToOrOther<T> (this IConvertible obj, T other) { try { return To<T>(obj); } catch { return other; } } public static bool ToOrOther<T> (this IConvertible obj, out T newObj, T other) { try { newObj = To<T>(obj); return true; } catch { newObj = other; return false; } } public static T ToOrNull<T> (this IConvertible obj) where T : class { try { return To<T>(obj); } catch { return null; } } public static bool ToOrNull<T> (this IConvertible obj, out T newObj) where T : class { try { newObj = To<T>(obj); return true; } catch { newObj = null; return false; } }


Hay una solución genérica (para cualquier tipo). La usabilidad es buena, pero la implementación debería mejorarse: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

Esto le permite escribir un código muy limpio como este:

string value = null; int? x = value.ConvertOrDefault<int?>();

y también:

object obj = 1; string value = null; int x = 5; if (value.TryConvert(out x)) Console.WriteLine("TryConvert example: " + x); bool boolean = "false".ConvertOrDefault<bool>(); bool? nullableBoolean = "".ConvertOrDefault<bool?>(); int integer = obj.ConvertOrDefault<int>(); int negativeInteger = "-12123".ConvertOrDefault<int>(); int? nullableInteger = value.ConvertOrDefault<int?>(); MyEnum enumValue = "SecondValue".ConvertOrDefault<MyEnum>(); MyObjectBase myObject = new MyObjectClassA(); MyObjectClassA myObjectClassA = myObject.ConvertOrDefault<MyObjectClassA>();


Me gusta la respuesta de Joel, pero la modifiqué ligeramente, ya que no soy partidario de comer excepciones.

/// <summary> /// Converts a string to the specified nullable type. /// </summary> /// <typeparam name="T">The type to convert to</typeparam> /// <param name="s">The string to convert</param> /// <returns>The nullable output</returns> public static T? ToNullable<T>(this string s) where T : struct { if (string.IsNullOrWhiteSpace(s)) return null; TypeConverter conv = TypeDescriptor.GetConverter(typeof (T)); return (T) conv.ConvertFrom(s); } /// <summary> /// Attempts to convert a string to the specified nullable primative. /// </summary> /// <typeparam name="T">The primitive type to convert to</typeparam> /// <param name="data">The string to convert</param> /// <param name="output">The nullable output</param> /// <returns> /// True if conversion is successfull, false otherwise. Null and whitespace will /// be converted to null and return true. /// </returns> public static bool TryParseNullable<T>(this string data, out T? output) where T : struct { try { output = data.ToNullable<T>(); return true; } catch { output = null; return false; } }


Mi ejemplo para tipos anónimos:

private object ConvertNullable(object value, Type nullableType) { Type resultType = typeof(Nullable<>).MakeGenericType(nullableType.GetGenericArguments()); return Activator.CreateInstance(resultType, Convert.ChangeType(value, nullableType.GetGenericArguments()[0])); } ... Type anonimousType = typeof(Nullable<int>); object nullableInt1 = ConvertNullable("5", anonimousType); // or evident Type Nullable<int> nullableInt2 = (Nullable<int>)ConvertNullable("5", typeof(Nullable<int>));


No hay forma de evitar esto. Nullable, al igual que su método, está limitado a usar solo tipos de valores como argumento. String es un tipo de referencia y, por lo tanto, es incompatible con esta declaración.


Otra cosa a tener en cuenta es que la cadena en sí podría ser nula.

public static Nullable<T> ToNullable<T>(this string s) where T: struct { Nullable<T> result = new Nullable<T>(); try { if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0) { TypeConverter conv = TypeDescriptor.GetConverter(typeof(T)); result = (T)conv.ConvertFrom(s); } } catch { } return result; }


Otra variación Éste

  • No traga excepciones
  • Lanza una NotSupportedException si el tipo no se puede convertir desde una string . Por ejemplo, una estructura personalizada sin un convertidor de tipo.
  • De lo contrario, devuelve un (T?)null si la cadena no puede analizar. No es necesario verificar nulos o espacios en blanco.

using System.ComponentModel; public static Nullable<T> ToNullable<T>(this string s) where T : struct { var ret = new Nullable<T>(); var conv = TypeDescriptor.GetConverter(typeof(T)); if (!conv.CanConvertFrom(typeof(string))) { throw new NotSupportedException(); } if (conv.IsValid(s)) { ret = (T)conv.ConvertFrom(s); } return ret; }


Puede intentar usar el siguiente método de extensión:

public static T? GetValueOrNull<T>(this string valueAsString) where T : struct { if (string.IsNullOrEmpty(valueAsString)) return null; return (T) Convert.ChangeType(valueAsString, typeof(T)); }

De esta manera puedes hacer esto:

double? amount = strAmount.GetValueOrNull<double>(); int? amount = strAmount.GetValueOrNull<int>(); decimal? amount = strAmount.GetValueOrNull<decimal>();


Puede usar lo siguiente con objetos, desafortunadamente esto no funciona con cadenas.

double? amount = (double?)someObject;

Lo uso para envolver una variable de sesión en una propiedad (en una página base) ... así que mi uso real es (en mi página base):

public int? OrganisationID { get { return (int?)Session[Constants.Session_Key_OrganisationID]; } set { Session[Constants.Session_Key_OrganisationID] = value; } }

Puedo verificar null en la lógica de la página:

if (base.OrganisationID == null) // do stuff


public static class GenericExtension { public static T? ConvertToNullable<T>(this String s) where T : struct { try { return (T?)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(s); } catch (Exception) { return null; } } }