Estoy usando la función IsNumeric() en mi código para validar números.

IsNumeric(100) - cierto, IsNumeric(-100) - cierto, IsNumeric(+100) - cierto,

IsNumeric(100-) - verdadero - Tengo dudas al respecto. (100-) ¿Es este un número válido? IsNumeric () devuelve verdadero a este valor.

    Dim latitude As String = "12.56346-"
    If IsNumeric(latitude) Then
        If (Convert.ToDouble(latitude) >= -90 And Convert.ToDouble(latitude) <= 90) Then
            isValidLatitude.Text = "true"
        Else
            isValidLatitude.Text = "false"
        End If
     Else
        isValidLatitude.Text = "false"
     End If

Error al convertir latitude a doble

Input string was not in a correct format.
2
Vijay 29 may. 2020 a las 08:36

3 respuestas

La mejor respuesta

Nota: mis respuestas anteriores eran incorrectas al suponer que era un error. Como dice la respuesta de @Damien_The_Unbeliever, esta función intenta validar la cadena como muchos tipos de datos. Y en realidad, el valor "100-" es un número válido Decimal. Es por eso que devuelve verdadero (ya que es un Decimal "válido") pero da una excepción al convertir a Doble (ya que no es un Doble válido). @Damien_The_Unbeliever realmente merece tu +1 por señalar eso.

De la documentación (que muestra todos los tipos de datos que IsNumeric intenta validar):

IsNumeric devuelve True si el tipo de datos de Expression es Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong o UShort. También devuelve True si Expression es un Char, String u Object que se puede convertir con éxito en un número. La expresión puede contener caracteres no numéricos. IsNumeric devuelve True si Expression es una cadena que contiene un número hexadecimal u octal válido. IsNumeric también devuelve True si Expression contiene una expresión numérica válida que comienza con un carácter + o - o contiene comas.

Además, @CaiusJard hizo una buena búsqueda y señaló que los métodos internos utilizan una opción NumberStyles.AllowTrailingSign, que permite este comportamiento.


Ok, ahora a la solución:

Simplemente use un método TryParse, de su tipo de datos deseado (int, long, etc.). Lo bueno es que se comportará exactamente como espera, y si el análisis es exitoso, ¡tenemos el valor analizado ya disponible para usar!

if (Int32.TryParse(value, out int number))
{
    // String is a valid number, and is already parsed in the 'number' variable!
}

else
{
    // String is not a valid number!
}


Versión VB.Net de la solución:

Dim value As String = "12.56346-"
Dim number As Double = 0
If Double.TryParse(value, number) Then
    ' String is a valid number, and is already parsed in the "number" variable!
    isValidLatitude.Text = "true"
Else
    ' String is not a valid number!
    isValidLatitude.Text = "false"
End If
3
Vitox 29 may. 2020 a las 09:30

IsNumeric responde una pregunta que ninguna persona cuerda quiere hacer. Como se cita en la respuesta de Vitox:

IsNumeric devuelve True si el tipo de datos de Expression es Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong o UShort. También devuelve True si Expression es un Char, String u Object que se puede convertir con éxito en un número.

Tenga en cuenta que no le dice que la cadena dada se puede convertir a todos tipos numéricos. Le dice que la cadena se puede convertir a al menos un tipo numérico. Y, por supuesto, para los puntos de mal estilo adicionales, no le dice a qué tipos se puede convertir la cadena.

Decimal.Parse("100-") se ejecutará perfectamente y le dará un Decimal que contiene un valor de -100.

Entonces, no es un error , es una mala función que se ha retenido por razones de compatibilidad con versiones anteriores. Hoy en día, sabemos mejor y queremos probar si una cadena se puede convertir a un tipo de datos específico , para lo cual se diseñó la familia de funciones TryParse.

2
Damien_The_Unbeliever 29 may. 2020 a las 08:03

IsNumeric es de Microsoft.VisualBasic namespace / dll, un montón de cosas de ayuda destinadas a ayudar a los programadores de VB6 a obtener su código / conocimiento VB6 arcano trabajando en VB.NET

Notará que si usa otras funciones del mismo dll, como Microsoft.VisualBasic.Conversion.Int(), o usa convertidores VB.NET dedicados, como CInt o CDbl, estos también enfrentarán un signo menos firmar y devolver un valor negativo

Si desea prescindir de las formas antiguas de VB6, use TryParse de un tipo numérico ... pero, en general, sea coherente / si usa una función de Microsoft.VisualBasic para determinar si se puede realizar una conversión, use la conversión vb porque dentro de en sí mismo, el paquete será coherente, pero entre Microsoft.VB y el sistema .net normal hay algunas diferencias de comportamiento


Editar:

Un par de personas se han estado preguntando sobre el código fuente y cómo usa TryParse, entonces ¿por qué no funciona como usar TryParse directamente?

Microsoft.VisualBasic.Information.IsNumeric() usa Microsoft.VisualBasic.CompilerServices.DoubleType.TryParse() para determinar si una expresión es numérica. Este DoubleType.TryParse no es lo mismo que Double.TryParse: es un método auxiliar nuevamente en el espacio de nombres de VB que establece específicamente el indicador NumberStyles.AllowTrailingSign entre muchos otros indicadores. Al analizar el número (primero como no relacionado con la moneda, usando Double.Parse, luego, si falla, se realiza un segundo intento usando valores ajustados para las pruebas relacionadas con la moneda), este indicador AllowTrailingSign se considerará junto con otras reglas de formato de números regionales para determinar si el valor pasado es numérico

Notarás que en una máquina que obedece a una cultura de formato de número de EE. UU., Una cadena de "(100 $)" también se declara como numérica, pero llamar Double.TryParse("(100$)", x) también devolverá falso. Los métodos de ayuda de VB aquí son mucho más liberales en lo que aceptan que los métodos del Sistema, porque le dicen a los métodos del Sistema que sean más liberales de lo que son por defecto

Como se señaló, siempre he considerado el espacio de nombres Microsoft.VisualBasic como un grupo de métodos auxiliares destinados a permitir que el antiguo código VB6 terrible se pegue en VB.NET y funcione con un mínimo de violín. No recomendaría usarlo para nuevos proyectos y elimino la referencia cuando trabajo en VB.NET, utilizándolo para admitir las nociones VB6 de "simplemente colocar cualquier cosa, de cualquier tipo, y probablemente lo resolverá y trabajo ... y si no es así, siempre podemos continuar con el error "luego debería descartarse en favor de la precisión y exactitud sobre las operaciones ejecutadas y su intención

7
Caius Jard 29 may. 2020 a las 08:29