2011-11-30 11 views
9

Estoy tratando de convertir un decimal a un número entero de forma segura.C# convertir un decimal a un int con seguridad

Algo así como

public static bool Decimal.TryConvertToInt32(decimal val, out int val) 

esto devolverá false si no lo puede convertir en un entero, y la verdadera w/salida de éxito si se puede.

Esto es para evitar la captura de la OverflowException en el método decimal.ToInt32. ¿Cuál es la forma más fácil de hacer esto?

+1

Sólo hay 2 casos en los que se lanza que OverflowException, es decir, x int.MaxValue puede no sólo tiene que utilizar un 'if'? – harold

+2

¿Qué quieres que haga si se da, digamos, 0.5? –

+1

¿Desea redondear o truncar el decimal? – AllenG

Respuesta

9

aquí:

public static bool TryConvertToInt32(decimal val, out int intval) 
{ 
    if (val > int.MaxValue || val < int.MinValue) 
    { 
     intval = 0; // assignment required for out parameter 
     return false; 
    } 

    intval = Decimal.ToInt32(val); 

    return true; 
} 
+1

Tenga en cuenta que todavía necesita asignar 'intval' en la ruta' false'. –

+0

@AnthonyPegram - Gracias. – Oded

2

Compare el decimal contra int.MinValue y int.MaxValue antes de la conversión.

3

que iba a escribir un método de extensión para decimal clase como esta:

public static class Extensions 
{ 
    public static bool TryConvertToInt32(this decimal decimalValue, out int intValue) 
    { 
     intValue = 0; 
     if ((decimalValue >= int.MinValue) && (decimalValue <= int.MaxValue)) 
     { 
      intValue = Convert.ToInt32(decimalValue); 
      return true; 
     } 
     return false; 
    } 
} 

Usted puede usarlo de esa manera:

if (decimalNumber.TryConvertToInt32(out intValue)) 
{ 
    Debug.WriteLine(intValue.ToString()); 
} 
0

Qué le pasa a usando Int32.TryParse (cadena)?

+0

No me interesa convertir el decimal en una cadena y luego volver a un entero. Esto costaría mucho rendimiento y no manejaría directamente decimales no enteros. – Superman

+0

Por supuesto que lo haría. Si haces Int32.TryParse ("3.14", d) obtendrías un resultado Falso. –

0

Por qué estás tratando de evitar la captura de la OverflowException? Está ahí por una razón y deberías atraparlo totalmente al llamar al . Las excepciones se usan ampliamente en todo el marco y los usuarios deberían captarlas. Los métodos tratan pueden ayudarle a su alrededor para hacer el código más estricto y más limpia, pero que el marco no tiene un método adecuado (Decimal.TryConvertToInt32() en este caso) la captura de OverflowException es lo más apropiado para hacerlo. En realidad, es más claro que crear una clase de extensión o escribir su propio método estático (ambos implican escribir su propio código donde el marco ya le está dando esta funcionalidad).

+1

¿Estás sugiriendo que debe siempre * * capturar excepciones, que debe * * Nunca tratar de evitarlos? Si es así, es un mal consejo. Absolutamente evítelos cuando sea posible (validando contra sus causas conocidas, por ejemplo), y solo recójalos cuando tenga los medios para tratarlos. Las excepciones son caras y no deben usarse para el flujo de control. –

+0

Tienes razón y agradezco el comentario. Depende del desarrollador determinar si esto ocurrirá con poca frecuencia o con frecuencia. En mi experiencia, algo como OverflowException para convertir Decimal.ToInt32 solo ocurriría en raras ocasiones y un manejador de excepciones funcionaría bien para establecer el resultado de manera apropiada. Pero depende del escenario, y de nuevo realmente aprecio que añadas esta importante nota sobre el desempeño de excepciones. – mattypiper

+0

Lanzar y atrapar una excepción es costoso.La configuración de un bloque try/catch no es así, y si la condición que causa la excepción _almost never never_ ocurre, puede ser más barato en promedio que la validación [la validación se repetirá en la conversión en sí misma] – Random832

Cuestiones relacionadas