csharp-conversion-tipos-cast

Convertir entre tipos con Cast en C#

La conversión de tipos, también conocida como casting o coerción, es el proceso de transformar un valor de un tipo de dato a otro.

Esto puede ser necesario cuando se trabaja con distintos tipos de datos y se requiere que un valor específico sea tratado como otro tipo.

Existen dos tipos principales de conversiones en C#, conversiones implícitas y conversiones explícitas.

Conversiones Implícitas

Las conversiones implícitas son aquellas que el compilador realiza automáticamente sin necesidad de una intervención explícita por parte del programador.

Esto es posible cuando no hay riesgo de pérdida de datos, o cuando el tipo de dato de destino es más grande que el tipo de dato de origen.

Por ejemplo, si tenemos una variable de tipo int y queremos asignar su valor a una variable de tipo long, no es necesario realizar ninguna conversión explícita, ya que C# realizará automáticamente la conversión implícita:

int numeroEntero = 10;
long numeroLargo = numeroEntero;

En este caso, la variable numeroEntero se convierte implícitamente en long y se asigna a la variable numeroLargo.

Conversiones Explícitas

La conversión explícita, también conocida como casting, se utiliza cuando se requiere una conversión de datos que no puede realizarse automáticamente por el compilador. Esto puede ocurrir cuando hay riesgo de pérdida de datos.

Para realizar una conversión explícita en C#, es necesario utilizar el operador de casting

(tipoDato)objeto

Donde

  • tipoDato es el tipo de dato de destino
  • objeto es el objeto que se desea convertir.

Por ejemplo, si tenemos una variable de tipo double y queremos convertirla a un tipo int, necesitamos realizar una conversión explícita:

double numeroDecimal = 3.14;
int numeroEntero = (int)numeroDecimal;

En este caso, utilizamos el casting (int) para convertir la variable numeroDecimal a int. Es importante tener en cuenta que, en este ejemplo, se perderá la parte decimal del número original.

Conversión entre tipos de referencia

También es posible realizar conversiones entre tipos de referencia, como clases e interfaces. Estas conversiones pueden ser más complejas y requieren un buen entendimiento de la jerarquía de tipos y la herencia.

El cast entre tipos tipos referencia diferentes debe hacerse con cuidado, y solo si estamos seguros de que la conversión es válida.

Si la conversión no es válida, provocará un error en tiempo de ejecución 💥

Conversión de clases base a clases derivadas

public class Animal
{
    public void HacerSonido()
    {
        Console.WriteLine("Sonido de animal");
    }
}

public class Perro : Animal
{
    public void Ladrar()
    {
        Console.WriteLine("Guau!");
    }
}

public class Program
{
    public static void Main()
    {
        Animal miAnimal = new Perro(); // Conversión implícita de Perro a Animal
        Perro miPerro = (Perro)miAnimal; // Conversión explícita de Animal a Perro

        miPerro.Ladrar(); // Salida: Guau!
    }
}

En este ejemplo, miAnimal se convierte implícitamente a Animal al ser instanciado como Perro. Luego, se realiza una conversión explícita de Animal a Perro para acceder al método específico de la clase derivada Perro.

Uso de operadores is y as

Los operadores is y as facilitan la comprobación y conversión segura entre tipos de referencia.

Operador is

El operador is se utiliza para verificar si un objeto es de un tipo específico.

object obj = "Hola, Mundo!";
if (obj is string)
{
    Console.WriteLine("obj es una cadena");
}

Operador as

El operador as intenta convertir un objeto a un tipo especificado y devuelve null si la conversión falla.

object obj = "Hola, Mundo!";
string cadena = obj as string;

if (cadena != null)
{
    Console.WriteLine("La conversión fue exitosa: " + cadena);
}
else
{
    Console.WriteLine("La conversión falló");
}

Conversión definida por el usuario

C# permite definir conversiones personalizadas entre tipos mediante la sobrecarga de operadores de conversión implicit y explicit.

Conversión implícita definida por el usuario

public class Celsius
{
    public float Grados { get; set; }

    public Celsius(float grados)
    {
        Grados = grados;
    }

    public static implicit operator Fahrenheit(Celsius c)
    {
        return new Fahrenheit((c.Grados * 9 / 5) + 32);
    }
}

public class Fahrenheit
{
    public float Grados { get; set; }

    public Fahrenheit(float grados)
    {
        Grados = grados;
    }
}

public class Program
{
    public static void Main()
    {
        Celsius celsius = new Celsius(25);
        Fahrenheit fahrenheit = celsius; // Conversión implícita
        Console.WriteLine(fahrenheit.Grados); // Salida: 77
    }
}

Conversión explícita definida por el usuario

public class Celsius
{
    public float Grados { get; set; }

    public Celsius(float grados)
    {
        Grados = grados;
    }

    public static explicit operator Fahrenheit(Celsius c)
    {
        return new Fahrenheit((c.Grados * 9 / 5) + 32);
    }
}

public class Fahrenheit
{
    public float Grados { get; set; }

    public Fahrenheit(float grados)
    {
        Grados = grados;
    }
}

public class Program
{
    public static void Main()
    {
        Celsius celsius = new Celsius(25);
        Fahrenheit fahrenheit = (Fahrenheit)celsius; // Conversión explícita
        Console.WriteLine(fahrenheit.Grados); // Salida: 77
    }
}

Ejemplos prácticos

Vamos a ver algunos ejemplos de conversiones entre tipos básicos.

Conversión de int a float

int numeroEntero = 100;
float numeroFloat = numeroEntero; // Conversión implícita
Console.WriteLine(numeroFloat); // Salida: 100

Conversión de double a int

double numeroDoble = 123.456;
int numeroEntero = (int)numeroDoble; // Conversión explícita
Console.WriteLine(numeroEntero); // Salida: 123 (se pierde la parte decimal)

Conversión de char a int

char letra = 'A';
int codigoAscii = (int)letra; // Conversión explícita
Console.WriteLine(codigoAscii); // Salida: 65 (código ASCII de 'A')