2010-03-16 15 views
5

Aquí una pregunta más básica se le preguntó en una entrevista reciente MSpolimorfismo y C#

class A { 
    public virtual void Method1(){} 

    public void Method2() { 
     Method1(); 
    } 
} 

class B:A { 
    public override void Method1() { } 
} 

class main { 
    A obk = new B(); 
    obk.Method2(); 
} 

Entonces, ¿qué función se vuelve a llamar? Perdón por los errores tipográficos.

+22

¿Por qué no lo pruebas? –

+0

@Jeff: no importa; B.Method1() sigue siendo la función que se llama. – apandit

+0

Creo que de acuerdo con la VMT (Tabla de métodos vitales) se llamará a la versión más reciente del método reemplazado. por lo que puede ser B.Method1() – TalentTuner

Respuesta

12
B.Method1(); 

es llamado ya que anula correctamente el método virtual A.Method1();

5

En este caso se llama a B.Method1. Esto se debe a que, aunque la variable se escribe como A, el tipo real de la instancia es B. El CLR despacha políticamente llamadas al Method1 en función del tipo real de la instancia, no del tipo de la variable.

2

Se llama a B.Method1() debido a la anulación.

3

La regla es "miembro de anulación en la clase más derivada", que en este caso sería "B".

4

Method1 de la clase B serán llamados, como se puede ver mediante la ejecución del programa a continuación:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var b = new B(); 
     b.Method2(); 

     Console.ReadLine(); 
    } 
} 

class A 
{ 

    public virtual void Method1() 
    { 
     Console.WriteLine("Method1 in class A"); 
    } 

    public void Method2() 
    { 
     Method1(); 
    } 
} 

class B : A 
{ 
    public override void Method1() 
    { 
     Console.WriteLine("Method1 in class B"); 
    } 
} 
1

B.Method1 se llama, ya que se reemplaza en la definición de clase.

1

La pregunta es un poco ambiguo ... pero ...

obk.method2() se llama. A su vez, llama a obk.Method1, que, dado que es una instancia de B, ha sido reemplazado por B.Method1. Entonces, B.Method1 es lo que finalmente se llama.

0

Como todos los demás han dicho, se llama a B.Method2. Aquí es algunas otras piezas de información para entender lo que está pasando:

((A)B).Method2(); 
B.Method2(); 

Estos serán tanto llamar B.Method1(), ya que fue anulado correctamente. Para llamar al Método1 de A, debe haber una llamada base.Metodo1() hecha desde B (que a menudo, pero no siempre, se hace en la implementación de B.Método1).

Sin embargo, si B se definió de esta manera:

class B:A { 
new public void Method1() { } 

... luego de un Método1() se llama así porque Método1 no fue anulado en realidad, era ocultos y escondido fuera de las reglas del polimorfismo. En general, esto es típicamente algo malo de hacer. No siempre, pero asegúrese de saber muy bien lo que está haciendo y por qué lo hace si alguna vez hace algo como esto.

Por otro lado, usar nuevo de esta manera también hace algunas preguntas interesantes para la entrevista.