Conversiones de tipos (Guía de programación de C#)

Dado que C# tiene tipos estáticos en tiempo de compilación, después de declarar una variable, no se puede volver a declarar ni se le puede asignar un valor de otro tipo a menos que ese tipo sea convertible de forma implícita al tipo de la variable. Por ejemplo, string no se puede convertir de forma implícita a int. Por tanto, después de declarar i como un valor int, no se le puede asignar la cadena "Hello", como se muestra en el código siguiente:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

Pero es posible que en ocasiones sea necesario copiar un valor en una variable o parámetro de método de otro tipo. Por ejemplo, es posible que tenga una variable de entero que se necesita pasar a un método cuyo parámetro es de tipo double. O es posible que tenga que asignar una variable de clase a una variable de tipo de interfaz. Estos tipos de operaciones se denominan conversiones de tipos. En C#, se pueden realizar las siguientes conversiones de tipos:

  • Conversiones implícitas: no se requiere sintaxis especial porque la conversión siempre se realiza correctamente y no se pierde ningún dato. Los ejemplos incluyen conversiones de tipos enteros más pequeños a más grandes, y conversiones de clases derivadas a clases base.

  • Conversiones explícitas: las conversiones explícitas requieren una expresión Cast. La conversión es necesaria si es posible que se pierda información en la conversión, o cuando es posible que la conversión no sea correcta por otros motivos. Entre los ejemplos típicos están la conversión numérica a un tipo que tiene menos precisión o un intervalo más pequeño, y la conversión de una instancia de clase base a una clase derivada.

  • Conversiones definidas por el usuario: las conversiones definidas por el usuario usan métodos especiales que puede definir para habilitar conversiones explícitas e implícitas entre tipos personalizados que no tienen una relación de clase derivada de clase–base. Para obtener más información, vea Operadores de conversión definidos por el usuario.

  • Conversiones con clases del asistente: para realizar conversiones entre tipos no compatibles, como enteros y objetos System.DateTime, o cadenas hexadecimales y matrices de bytes puede usar la clase System.BitConverter, la clase System.Convert y los métodos Parse de los tipos numéricos integrados, como Int32.Parse. Para obtener más información, consulte Procedimiento Convertir una matriz de bytes en un valor int, Procedimiento Convertir una cadena en un número y Procedimiento Convertir cadenas hexadecimales en tipos numéricos.

Conversiones implícitas

Para los tipos numéricos integrados, se puede realizar una conversión implícita cuando el valor que se va a almacenar se puede encajar en la variable sin truncarse ni redondearse. Para los tipos enteros, esto significa que el intervalo del tipo de origen es un subconjunto apropiado del intervalo para el tipo de destino. Por ejemplo, una variable de tipo long (entero de 64 bits) puede almacenar cualquier valor que un tipo int (entero de 32 bits) pueda almacenar. En el ejemplo siguiente, el compilador convierte de forma implícita el valor de num en la parte derecha a un tipo long antes de asignarlo a bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Para obtener una lista completa de las conversiones numéricas implícitas, consulte la sección Conversiones numéricas implícitas del artículo Conversiones numéricas integradas.

Para los tipos de referencia, siempre existe una conversión implícita desde una clase a cualquiera de sus interfaces o clases base directas o indirectas. No se necesita ninguna sintaxis especial porque una clase derivada siempre contiene a todos los miembros de una clase base.

Derived d = new Derived();

// Always OK.
Base b = d;

Conversiones explícitas

Pero si no se puede realizar una conversión sin riesgo de perder información, el compilador requiere que se realice una conversión explícita, que se denomina conversión. Una conversión de tipos es una manera de informar explícitamente al compilador de que se pretende realizar la conversión y se es consciente de que se puede producir pérdida de datos o la conversión de tipos puede fallar en tiempo de ejecución. Para realizar una conversión, especifique el tipo al que se va a convertir entre paréntesis delante del valor o la variable que se va a convertir. El siguiente programa convierte un tipo double en un tipo int. El programa no se compilará sin la conversión.

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;
        System.Console.WriteLine(a);
    }
}
// Output: 1234

Para obtener una lista completa de las conversiones numéricas explícitas admitidas, consulte la sección Conversiones numéricas explícitas del artículo Conversiones numéricas integradas.

Para los tipos de referencia, se requiere una conversión explícita si es necesario convertir de un tipo base a un tipo derivado:

// Create a new derived type.
Giraffe g = new Giraffe();

// Implicit conversion to base type is safe.
Animal a = g;

// Explicit conversion is required to cast back
// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe)a;

Una operación de conversión entre tipos de referencia no cambia el tipo en tiempo de ejecución del objeto subyacente. Solo cambia el tipo del valor que se usa como referencia a ese objeto. Para obtener más información, vea Polimorfismo .

Excepciones de conversión de tipos en tiempo de ejecución

En algunas conversiones de tipos de referencia, el compilador no puede determinar si una conversión será válida. Es posible que una operación de conversión que se compile correctamente produzca un error en tiempo de ejecución. Como se muestra en el ejemplo siguiente, una conversión de tipos que produce un error en tiempo de ejecución hace que se produzca un InvalidCastException.

class Animal
{
    public void Eat() => System.Console.WriteLine("Eating.");

    public override string ToString() => "I am an animal.";
}

class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
    static void Main()
    {
        Test(new Mammal());

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }

    static void Test(Animal a)
    {
        // System.InvalidCastException at run time
        // Unable to cast object of type 'Mammal' to type 'Reptile'
        Reptile r = (Reptile)a;
    }
}

El método Test tiene un parámetro Animal, por lo que la conversión explícita del argumento a en un Reptile supone una suposición peligrosa. Es más seguro no hacer suposiciones, sino comprobar el tipo. C# proporciona el operador is para permitir probar la compatibilidad antes de realizar una conversión. Para obtener más información, consulte Procedimiento para convertir de forma segura mediante la coincidencia de patrones y los operadores is y as.

Especificación del lenguaje C#

Para obtener más información, vea la sección sobre conversiones de la Especificación del lenguaje C#.

Consulte también