JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Diferencias entre conversiones de tipos explícitas y mediante la clase Convert

Encajar¿Qué diferencia existe en C# entre hacer una conversión implícita y usar un método de la clase Convert? 

En realidad lo que hacen por debajo la mayor parte de las veces los métodos de Convert es llamar a conversiones implícitas. Es fácil comprobarlo viendo el código fuente de la plataforma con, por ejemplo, Reflector.

Sin embargo sí puede haber diferencias cuando se hacen conversiones entre tipos que pueden llevar a pérdida de información. Por ejemplo convertir desde un Int32 a un Int16, donde es posible que se pueda perder información ya que un Int32 puede contener números mayores que un Int16.

En estos casos sí que podría haber diferencias ya que las conversiones explícitas y los métodos de conversión se comportan de forma ligeramente distinta puesto que los últimos introducen alguna lógica para avisarte de que se producen excepciones.

Por ejemplo, si usas este código:

double d = 123456.76;
long l = (long)d;
long l2 = Convert.ToInt32(d);

La variable "l" contendrá el número 123456, pero la variable "l2" contendrá 123457. El motivo sale enseguida si examinas el código del método Convert.ToInt32:

public static int ToInt32(double value)
    {
        if (value >= 0.0)
        {
            if (value < 2147483647.5)
            {
                int num = (int) value;
                double num2 = value - num;
                if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))
                {
                    num++;
                }
                return num;
            }
        }
        else if (value >= -2147483648.5)
        {
            int num3 = (int) value;
            double num4 = value - num3;
            if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & 1) != 0)))
            {
                num3--;
            }
            return num3;
        }
        throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
    }

Fíjate que lo que hace es redondear los decimales de forma diferente, y además si el valor no está en el rango permitido, devuelve una excepción porque perderías información, cosa que no ocurre con una conversión explícita en este caso.

Otro ejemplo más fácil de ver:

int i = 32765;
byte b = (byte) i;
int b2 = Convert.ToByte(i);

En este caso "b" contendrá el valor 253 porque la conversión explícita ha convertido a Byte incluso con pérdida de información. Sin embargo el método ToByte devuelve una excepción de de desbordamiento, porque se perdería información. El código del método ToByte es similar al anterior.

En MSDN detallan las conversiones que pierden y no pierden información.

¡Espero que te resulte útil!

José Manuel Alarcón
Banner

Agregar comentario