Polimorfismo en C#

Meleagant

A ver si alguien puede echarme un cable con esto, que algo estoy haciendo mal pero no caigo en qué.

Tengo una clase A con su método virtual Método, y una clase que hereda de A, (public class B : A) con su método Método modificado (public override void Método()).

Si instancio un objeto de la clase B, todo funciona como debería y se ejecuta el Método de la clase B.

Sin embargo, tengo una lista List<A> donde voy metiendo instancias de objetos B, C, D, E... todos heredados de A, y al llamar al Método de cada uno de ellos, lo que se ejecuta es el Método de A, y no el correspondiente al tipo de objeto que son.

¿Se me ha pasado algo por alto? ¿Estoy haciendo alguna burrada?

Soltrac

Haz una cosa, q me está sonando raro.

Si haces:

A var = new B();
var.Metodo();

te ejecuta el de A o el de B?

2 respuestas
Meleagant

#2 Con eso me pasa lo mismo, de hecho antes lo tenía así, pero como no funcionaba decidí probar creando los objetos de la forma:

List<A> lista = new List<A> ( );

B b = new B();
C c = new C();

lista.add(B);
lista.add(C);

Soltrac

Déjame hacer la prueba y hago el update 1 sec....

Update:


    private class A
    {
        public virtual int DoWork() { return 0; }
    }

    private class B : A
    {
        public override int DoWork()
        {
            return 1;
        }
    }

    A var = new B();
    int result = var.DoWork();

Y result me devuelve 1. Tienes algo mal. Copia aquí tu código que se te escapa algo.

1 respuesta
Meleagant

#4 No, si esa prueba ya la he hecho yo xD

El tema es que aparte de comprobar que el método es virtual en la clase padre, y que está declarado como override en la clase hijo, no sé qué más mirar. ¿Alguna idea de por dónde pueden ir los tiros?

#7 No, no es un problema de base.Metodo(); porque he ido haciendo debug y no llega a entrar en el método de B, sino que directamente ejecuta el de A.

Pasa con varios métodos, algunos tienen base.Método() y otros no. Pero en ninguno de ellos llega a entrar.

Le daré más vueltas a ver, pero la verdad es que no le encuentro explicación. Muchas gracias por la ayuda :)

1 respuesta
Sol1dSnake

#2 El de B supongo. Pero eso quizas te de un error o almenos un warrning.

1 respuesta
Soltrac

#5 Pues si esa prueba está mal es que tienes algo mal en el código.

Comprueba que no se te haya colado un base.DoWork() que esté ejecutando el código del padre.

#6 No hombre, como va a dar error o warning xDDDDD.

Edit: C# permite hacer eso, no tienes que tipar la variable.

#5 Insisto, copia la declaración de las clases, la función método (no es necesario q copies lo de dentro) y lo que haces en list.

Mételo en un code que se te está escapando algo que no ves.

2 respuestas
Meleagant

#7 Bueno, el código es un poco guarreras porque lo he ido cambiando sobre la marcha:

Clase Padre
Clase Hijo
Código que instancia ambas:

Básicamente ambos métodos son casi iguales, cambia un color. Esto es porque el Nivel1 no varía, pero en otros varía mucho más. Como ya digo, se podía hacer mucho más limpio pero ahora no es mi prioridad.

Soltrac

Acabo de hacer esto, en .NEt 3.5 y en .NET 4 y me funciona perfectamente

class Partida
        {
            public Partida(Stream tamano)
            {
            }

        public virtual void Draw(string theSpriteBatch)
        {
            int a = 2;
        }
    }

    class Nivel1 : Partida
    {

        public Nivel1(Stream tamano)
            : base(tamano)
        {
        }

        public override void Draw(string theSpriteBatch)
        {
            int a = 1;
        }
    }

    public Form1()
    {
        List<Partida> partidas = new List<Partida>();
        Nivel1 _nivel1 = new Nivel1(new MemoryStream());
        partidas.Add(_nivel1);
        partidas.ElementAt(0).Draw("pepe");
}

Haz una cosa, en el Draw final, cuando pones el debugger, partidas.ElementAt(level) que tipo te dice que es? Nivel1 o Partida?

1 respuesta
Meleagant

#9

Me dice que es Nivel1.

Me tiene totalmente desconcertado. Igual tiene algo que ver con el Framework de XNA, pero me extrañaría mucho que cambie el funcionamiento normal de C#.

1 respuesta
Soltrac

#10 Copia y pega mi código en XNA y dime por donde entra. Es que no tengo el framework de XNA instalado.

1 respuesta
Meleagant

#11

Solucionado.

Resúltase que soy idiota y el índice (level) debería empezar en 0, no en 1 (es de cajón, ya lo sé). Por tanto el nivel inicial era Nivel2 y no Nivel1.

En Nivel2 no había puesto override.

Estoy buscando, pero no encuentro un facepalm lo suficientemente digno de semejante cagada.

Muchas gracias por la ayuda, si alguna vez pasas por Burgos te invito a unas copas por las molestias xD

1 respuesta
Soltrac

#12 Sabía q había algo mal xDDDD.

Pero bueno, nos pasa a todos, faltaría más.

elkaoD

OMG llevo todo el día siguiendo el hilo intrigado por qué cojones pasaría xD

Usuarios habituales

  • elkaoD
  • Soltrac
  • Meleagant
  • Sol1dSnake