una ultimo recortar quitar parte extraer eliminar ejemplos caracteres caracter cadena buscar c# .net string .net-3.5 nullable

ultimo - split c#



Cómo analizar una cadena en un int nulable (21)

Estoy más interesado en saber si hay un método de marco integrado que se analizará directamente en un int.

No hay

Estoy queriendo analizar una cadena en un int anulable en C #. es decir. Quiero recuperar el valor int de la cadena o nulo si no se puede analizar.

Esperaba que esto funcionara

int? val = stringVal as int?;

Pero eso no funcionará, así que la forma en que lo estoy haciendo ahora es que escribí este método de extensión.

public static int? ParseNullableInt(this string value) { if (value == null || value.Trim() == string.Empty) { return null; } else { try { return int.Parse(value); } catch { return null; } } }

¿Hay una mejor manera de hacer esto?

EDIT: Gracias por las sugerencias de TryParse, lo sabía, pero funcionó igual. Estoy más interesado en saber si hay un método de marco integrado que se analizará directamente en un int.


Glenn Slaven : ¿Estoy más interesado en saber si hay un método de marco incorporado que se analizará directamente en un int.

Existe un enfoque que se analizará directamente en un int anulable (y no solo en el int) si el valor es válido como nulo o cadena vacía, pero arroja una excepción para los valores no válidos, por lo que deberá detectar la excepción y devolver el valor predeterminado. para esas situaciones:

public static T Parse<T>(object value) { try { return (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value.ToString()); } catch { return default(T); } }

Este enfoque todavía se puede utilizar para análisis no anulables así como anulables:

enum Fruit { Orange, Apple } var res1 = Parse<Fruit>("Apple"); var res2 = Parse<Fruit?>("Banana"); var res3 = Parse<int?>("100") ?? 5; //use this for non-zero default var res4 = Parse<Unit>("45%");

NB: hay un método IsValid en el convertidor que puede usar en lugar de capturar la excepción (las excepciones lanzadas generan una sobrecarga innecesaria si se espera). Desafortunadamente, solo funciona desde .NET 4, pero todavía hay un problema en el que no se comprueba la configuración regional cuando se validan los formatos correctos de DateTime.


Al usar delegados, el siguiente código es capaz de proporcionar reutilización si se encuentra necesitando el análisis anulable para más de un tipo de estructura. He mostrado las versiones .Parse () y .TryParse () aquí.

Este es un ejemplo de uso:

NullableParser.TryParseInt(ViewState["Id"] as string);

Y aquí está el código que te lleva allí ...

public class NullableParser { public delegate T ParseDelegate<T>(string input) where T : struct; public delegate bool TryParseDelegate<T>(string input, out T outtie) where T : struct; private static T? Parse<T>(string input, ParseDelegate<T> DelegateTheParse) where T : struct { if (string.IsNullOrEmpty(input)) return null; return DelegateTheParse(input); } private static T? TryParse<T>(string input, TryParseDelegate<T> DelegateTheTryParse) where T : struct { T x; if (DelegateTheTryParse(input, out x)) return x; return null; } public static int? ParseInt(string input) { return Parse<int>(input, new ParseDelegate<int>(int.Parse)); } public static int? TryParseInt(string input) { return TryParse<int>(input, new TryParseDelegate<int>(int.TryParse)); } public static bool? TryParseBool(string input) { return TryParse<bool>(input, new TryParseDelegate<bool>(bool.TryParse)); } public static DateTime? TryParseDateTime(string input) { return TryParse<DateTime>(input, new TryParseDelegate<DateTime>(DateTime.TryParse)); } }


Encontré este, que cumplió con mis requisitos (quería que mi método de extensión emulara lo más cerca posible del retorno de TryParse del marco, pero sin los bloques try {} catch {} y sin que el compilador se quejara de inferir un tipo anulable dentro del método de marco)

private static bool TryParseNullableInt(this string s, out int? result) { int i; result = int.TryParse(s, out i) ? (int?)i : null; return result != null; }


Encontré y adapté algo de código para una clase de NullableParser genérico. El código completo está en mi blog Nullable TryParse

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Globalization; namespace SomeNamespace { /// <summary> /// A parser for nullable types. Will return null when parsing fails. /// </summary> /// <typeparam name="T"></typeparam> /// public static class NullableParser<T> where T : struct { public delegate bool TryParseDelegate(string s, out T result); /// <summary> /// A generic Nullable Parser. Supports parsing of all types that implements the tryParse method; /// </summary> /// <param name="text">Text to be parsed</param> /// <param name="result">Value is true for parse succeeded</param> /// <returns>bool</returns> public static bool TryParse(string s, out Nullable<T> result) { bool success = false; try { if (string.IsNullOrEmpty(s)) { result = null; success = true; } else { IConvertible convertableString = s as IConvertible; if (convertableString != null) { result = new Nullable<T>((T)convertableString.ToType(typeof(T), CultureInfo.CurrentCulture)); success = true; } else { success = false; result = null; } } } catch { success = false; result = null; } return success; } } }


Esta solución es genérica sin gastos indirectos de reflexión.

public static Nullable<T> ParseNullable<T>(string s, Func<string, T> parser) where T : struct { if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(s.Trim())) return null; else return parser(s); } static void Main(string[] args) { Nullable<int> i = ParseNullable("-1", int.Parse); Nullable<float> dt = ParseNullable("3.14", float.Parse); }


Lo siento, no pude resistirme, tuve este problema y Google me trajo aquí, pero terminé con esto (después de todo, ¡un if y 2 s de retorno son demasiado largos!):

int? ParseNInt (string val) { int i; return int.TryParse (val, out i) ? (int?) i : null; }

En una nota más seria, intente no mezclar int , que es una palabra clave de C #, con Int32 , que es un tipo BCL de .NET Framework; aunque funciona, solo hace que el código se vea desordenado.


Lo siguiente debería funcionar para cualquier tipo de estructura. Está basado fuera de código por Matt Manela de los foros de MSDN . Como Murph señala, el manejo de excepciones podría ser costoso en comparación con el uso del método TryParse dedicado de los tipos.

public static bool TryParseStruct<T>(this string value, out Nullable<T> result) where T: struct { if (string.IsNullOrEmpty(value)) { result = new Nullable<T>(); return true; } result = default(T); try { IConvertible convertibleString = (IConvertible)value; result = new Nullable<T>((T)convertibleString.ToType(typeof(T), System.Globalization.CultureInfo.CurrentCulture)); } catch(InvalidCastException) { return false; } catch (FormatException) { return false; } return true; }

Estos fueron los casos de prueba básicos que utilicé.

string parseOne = "1"; int? resultOne; bool successOne = parseOne.TryParseStruct<int>(out resultOne); Assert.IsTrue(successOne); Assert.AreEqual(1, resultOne); string parseEmpty = string.Empty; int? resultEmpty; bool successEmpty = parseEmpty.TryParseStruct<int>(out resultEmpty); Assert.IsTrue(successEmpty); Assert.IsFalse(resultEmpty.HasValue); string parseNull = null; int? resultNull; bool successNull = parseNull.TryParseStruct<int>(out resultNull); Assert.IsTrue(successNull); Assert.IsFalse(resultNull.HasValue); string parseInvalid = "FooBar"; int? resultInvalid; bool successInvalid = parseInvalid.TryParseStruct<int>(out resultInvalid); Assert.IsFalse(successInvalid);


Me doy cuenta de que este es un tema antiguo, pero no puedes simplemente:

(Nullable<int>)int.Parse(stringVal);

?


Nunca debe usar una excepción si no tiene que hacerlo: el gasto general es horrible.

Las variaciones en TryParse resuelven el problema: si desea ser creativo (para hacer que su código se vea más elegante) probablemente podría hacer algo con un método de extensión en 3.5, pero el código sería más o menos el mismo.


Prueba esto:

public static int? ParseNullableInt(this string value) { int intValue; if (int.TryParse(value, out intValue)) return intValue; return null; }


Puede hacer esto en una línea, utilizando el operador condicional y el hecho de que puede convertir null a un tipo que puede contener null (dos líneas, si no tiene un int preexistente, puede reutilizarlo para la salida de TryParse ):

Pre C # 7:

int tempVal; int? val = Int32.TryParse(stringVal, out tempVal) ? Int32.Parse(stringVal) : (int?)null;

Con la sintaxis actualizada de C # 7 que le permite declarar una variable de salida en la llamada de método, esto se vuelve aún más simple.

int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;


Puede olvidar todas las demás respuestas: hay una gran solución genérica: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

Esto te permite escribir código muy limpio como este:

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

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? nullableBoolean = "".ConvertOrDefault(); int integer = obj.ConvertOrDefault(); int negativeInteger = "-12123".ConvertOrDefault(); int? nullableInteger = value.ConvertOrDefault(); MyEnum enumValue = "SecondValue".ConvertOrDefault(); MyObjectBase myObject = new MyObjectClassA(); MyObjectClassA myObjectClassA = myObject.ConvertOrDefault();


Sentí que debería compartir el mío, que es un poco más genérico.

Uso:

var result = "123".ParseBy(int.Parse); var result2 = "123".ParseBy<int>(int.TryParse);

Solución:

public static class NullableParse { public static Nullable<T> ParseBy<T>(this string input, Func<string, T> parser) where T : struct { try { return parser(input); } catch (Exception exc) { return null; } } public delegate bool TryParseDelegate<T>(string input, out T result); public static Nullable<T> ParseBy<T>(this string input, TryParseDelegate<T> parser) where T : struct { T t; if (parser(input, out t)) return t; return null; } }

La primera versión es más lenta ya que requiere un try-catch pero se ve más limpia. Si no se llamará muchas veces con cadenas no válidas, no es tan importante. Si el rendimiento es un problema, tenga en cuenta que al usar los métodos TryParse, debe especificar el parámetro de tipo de ParseBy, ya que el compilador no puede deducirlo. También tuve que definir un delegado ya que la palabra clave out no se puede usar dentro de Func <>, pero al menos este compilador no requiere una instancia explícita.

Finalmente, puede usarlo también con otras estructuras, es decir, decimal, DateTime, Guid, etc.


Siento que mi solución es una solución muy limpia y agradable:

public static T? NullableParse<T>(string s) where T : struct { try { return (T)typeof(T).GetMethod("Parse", new[] {typeof(string)}).Invoke(null, new[] { s }); } catch (Exception) { return null; } }

Esta es, por supuesto, una solución genérica que solo requiere que el argumento genérico tenga un método estático "Parse (cadena)". Esto funciona para números, booleanos, DateTime, etc.


Sugeriría los siguientes métodos de extensión para el análisis de cadenas en el valor int con la capacidad de definir el valor predeterminado en caso de que el análisis no sea posible:

public static int ParseInt(this string value, int defaultIntValue = 0) { return int.TryParse(value, out var parsedInt) ? parsedInt : defaultIntValue; } public static int? ParseNullableInt(this string value) { if (string.IsNullOrEmpty(value)) return null; return value.ParseInt(); }


Sugiero código abajo. Puede trabajar con excepción, cuando se produjo un error de conversión.

public static class Utils { public static bool TryParse<Tin, Tout>(this Tin obj, Func<Tin, Tout> onConvert, Action<Tout> onFill, Action<Exception> onError) { Tout value = default(Tout); bool ret = true; try { value = onConvert(obj); } catch (Exception exc) { onError(exc); ret = false; } if (ret) onFill(value); return ret; } public static bool TryParse(this string str, Action<int?> onFill, Action<Exception> onError) { return Utils.TryParse(str , s => string.IsNullOrEmpty(s) ? null : (int?)int.Parse(s) , onFill , onError); } public static bool TryParse(this string str, Action<int> onFill, Action<Exception> onError) { return Utils.TryParse(str , s => int.Parse(s) , onFill , onError); } }

Use este método de extensión en el código (fill int? Propiedad de Age de una clase de persona):

string ageStr = AgeTextBox.Text; Utils.TryParse(ageStr, i => person.Age = i, exc => { MessageBox.Show(exc.Message); });

O

AgeTextBox.Text.TryParse(i => person.Age = i, exc => { MessageBox.Show(exc.Message); });


Viejo tema, pero ¿qué tal?

public static int? ParseToNullableInt(this string value) { return String.IsNullOrEmpty(value) ? null : (int.Parse(value) as int?); }

Me gusta esto mejor ya que el requriement donde analizar nulo, la versión TryParse no arrojaría un error en, por ejemplo, ToNullableInt32 (XXX). Eso puede introducir errores silenciosos no deseados.


int.TryParse es probablemente un poco más fácil:

public static int? ToNullableInt(this string s) { int i; if (int.TryParse(s, out i)) return i; return null; }

Edit @Glenn int.TryParse está "integrado en el marco". It y int.Parse son la forma de analizar cadenas a ints.


public static void Main(string[] args) { var myString = "abc"; int? myInt = ParseOnlyInt(myString); // null myString = "1234"; myInt = ParseOnlyInt(myString); // 1234 } private static int? ParseOnlyInt(string s) { return int.TryParse(s, out var i) ? i : (int?)null; }


var result = int.TryParse(foo, out var f) ? f : default(int?);

Fuentes: