Casting en C#: cuándo funciona y cuándo falla

Clase 5 de 35Curso de C# con .Net Core 2.1

Resumen

Domina el polimorfismo en C# con ejemplos claros en Visual Studio Code. Entiende cómo un Alumno se ve como ObjetoEscuela gracias a la herencia, cuándo un padre puede verse como su hijo mediante casting y qué ocurre si fuerzas conversiones que el compilador acepta pero fallan en runtime. Evita errores comunes y aprovecha este pilar de la programación orientada a objetos.

¿Qué es polimorfismo y por qué importa en C#?

El polimorfismo permite tratar objetos de clases hijas como instancias de su clase padre. Un Alumno es un ObjetoEscuela porque hereda de él. También es posible intentar el camino inverso: ver el padre como su hijo, pero solo si el objeto realmente es del tipo del hijo. De lo contrario, el casting compila, pero falla en tiempo de ejecución.

  • Un hijo puede verse como su padre sin problemas.
  • El padre solo puede verse como el hijo si el objeto interno es del tipo del hijo.
  • Forzar casting engaña al compilador, pero no al runtime.

¿Cómo se ve un alumno como objeto escuela?

  • Conversión ascendente (hijo → padre) segura.
  • Mismo objeto, interfaz de uso más general.
// Alumno hereda de ObjetoEscuela
Alumno alumno = new Alumno();
ObjetoEscuela ob = alumno; // upcasting seguro

// Válido si ob realmente contiene un Alumno
Alumno alumnoDeNuevo = (Alumno)ob; // downcasting correcto solo si ob es Alumno

¿Cuándo un padre puede verse como su hijo?

  • Si el objeto base es un “dummy” (no proviene del hijo), el casting compila si lo fuerzas, pero falla en ejecución.
ObjetoEscuela dummy = new ObjetoEscuela();
// Compila al forzar, pero fallará en runtime porque dummy no es Alumno
Alumno alumnoInvalido = (Alumno)dummy; // incorrecto

¿Cómo modelar evaluación y asignación de tipos sin errores?

Una Evaluación también es un ObjetoEscuela. Puedes crearla, asignar atributos clave y tratarla como su clase base. No puedes acceder a propiedades específicas (como Nota) desde la referencia de tipo base.

¿Cómo crear una evaluación y establecer atributos clave?

  • Asigna nombre y nota como diferenciadores.
  • La Asignatura requiere una instancia propia; no basta con un texto directo.
var evaluacion = new Evaluacion {
    Nombre = "Evaluación de matemáticas",
    Nota = 4.5f
    // Asignatura = new Asignatura { Nombre = "Matemáticas" }; // requiere instancia; se omitió en el ejemplo
};

¿Cómo asignar evaluación a un objeto base y qué limitaciones hay?

  • Tratar Evaluación como ObjetoEscuela funciona.
  • Acceder a Nota desde ObjetoEscuela no compila.
ObjetoEscuela obEval = evaluacion; // upcasting válido

float notaOk = evaluacion.Nota; // válido
// float notaError = obEval.Nota; // no existe Nota en ObjetoEscuela

¿Qué pasa al convertir evaluación en alumno?

Evaluación y Alumno comparten padre (ObjetoEscuela), pero no son compatibles entre sí.

  • Conversión directa Evaluación → Alumno: no permitida por el compilador.
  • Forzar primero a ObjetoEscuela y luego a Alumno elimina el error de compilación, pero falla en runtime porque el objeto real es una Evaluación.
Evaluacion evaluacion2 = new Evaluacion();

// No permitido: tipos distintos entre sí
// Alumno a = (Alumno)evaluacion2; // error de compilación

// Engaña al compilador, no al runtime
ObjetoEscuela baseOb = evaluacion2;    // upcasting
Alumno aForzado = (Alumno)baseOb;       // compila, pero fallará en ejecución

¿Qué prácticas seguras aplicar con polimorfismo y casts?

El polimorfismo es potente, pero un casting incorrecto rompe la ejecución. La clave es operar según el tipo real del objeto y no asumir compatibilidades que no existen entre clases hermanas.

¿Cuándo confiar en el compilador y cuándo validar?

  • Confía en el compilador para upcasting (hijo → padre).
  • Verifica el tipo real antes de downcasting (padre → hijo).
  • Evita forzar conversiones solo para “quitar” errores de compilación.

¿Qué idea clave recordar sobre evaluación y alumno?

  • Ambas heredan de ObjetoEscuela, pero no hay justificación para convertir Evaluación en Alumno.
  • Si fuerzas, el compilador “cree” que funcionará; el runtime mostrará que no.

¿Qué se construirá después con objeto escuela?

Se plantea una funcionalidad para que la escuela entregue todos sus objetos de tipo ObjetoEscuela. Servirá para explotar el polimorfismo de forma ordenada y segura.

¿Tienes dudas o un ejemplo propio con casting y herencia en C#? Compártelo y conversemos cómo mejorarlo.