2010-09-05 12 views
9
class Base 
{ 
    public virtual void MethodA(int x) 
    { 
     Console.WriteLine ("In Base Class"); 
    } 
} 

class Derived : Base 
{ 
    public override void MethodA(int x) 
    { 
     Console.WriteLine ("In derived INT)"); 
    } 

    public void MethodA(object o) 
    { 
     Console.WriteLine ("In derived OBJECT"); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Derived d = new Derived(); 
     int k = 20; 
     d.MethodA(k); 
    } 
} 

La salida que obtuve para esto es "En derivado OBJETO". ¿Cuál es la razón de este extraño comportamiento? Después de algunas investigaciones, descubrí que el motivo es , las firmas declaradas en la clase base se ignoran. ¿Por qué son ignorados?¿Por qué se ignoran las firmas declaradas en la clase base?

+1

+1 a la pregunta, estoy de acuerdo este es un comportamiento contrario a la intuición. –

+0

Estoy de acuerdo en que el comportamiento es extraño. Me gustaría saber: ¿estás preguntando esto porque realmente quieres hacer esto o porque tienes curiosidad? No veo una razón para implementar algo como esto, pero definitivamente me gustaría saber por qué sucede. –

+0

posible duplicado de [¿Cómo funciona el ocultamiento de métodos en C#? (Parte dos)] (http://stackoverflow.com/questions/710459/how-method-hiding-works-inc-c-part-two) –

Respuesta

6

Esto es por diseño y por una buena razón. Este diseño ayuda a prevenir el problema de clase base frágil. C# fue diseñado para hacer más fácil y seguro escribir componentes "versionados", y esta regla es una gran parte de eso.

Esta es una pregunta muy frecuente. Este es uno de los "informes de errores falsos" más comunes que obtenemos; es decir, alguien cree que encontró un error en el compilador cuando, de hecho, encontraron una característica.

Para una descripción de la función y por qué se diseñó la forma en que está, véase mi artículo sobre el tema:

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

Para más artículos sobre el tema de cómo las diversas lenguas frente a la frágil problema base de la Clase ver mi archivo de artículos sobre el tema:

http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/

2

El compilador en VC# 2008 comprueba las funciones disponibles no virtuales antes que las virtuales, al decidir qué llamar. Como su clase derivada tiene un MethodA (objeto) no virtual que se puede llamar, el compilador lo llama.

Si agrega un MethodA (objeto) virtual a Base, se llamará Derived.MethodA (int), porque entonces tanto MethodA (objeto) como MethodA (int) son virtuales.

No estoy lo suficientemente familiarizado con la especificación del lenguaje C# para saber si se trata de un comportamiento específico o un error en el compilador.

+0

De hecho, está en la especificación ECMA; primero se invocará no virtual. También tenga en cuenta que el método que se llama es determinado por el compilador para los métodos no virtuales, y por el tipo de tiempo de ejecución para los métodos virtuales. –

+0

Comprobé esto, pero ten cuidado de que Derived.MethodA (int) solo se invoque cuando agregas la palabra clave 'anular' a Derived.MethodA (object) (eso fue por supuesto). Sin él, se asume la palabra clave opcional 'nuevo' y Derived.MethodA (object) aún se llamará. – Gerard

Cuestiones relacionadas