2012-04-02 9 views
7

Tengo el siguiente código simple¿Cómo llamar al método anulado que tiene sobrecargas?

abstract class A 
{ 
    public abstract void Test(Int32 value); 
} 

class B : A 
{ 
    public override void Test(Int32 value) 
    { 
     Console.WriteLine("Int32"); 
    } 

    public void Test(Double value) 
    { 
     Test((Int32)1); 
    } 
} 

Cuando me encontré con este código de la línea de prueba ((Int32) 1) provoca desbordamiento de pila debido a la recursividad infinita. La única forma posible para llamar correctamente método adecuado (con el parámetro de número entero) que he encontrado es

(this as A).Test(1); 

Pero esto no es apropiado para mí, debido a que ambos métodos de prueba son públicos y estoy dispuesto a los usuarios para poder llamar tanto ¿método?

Respuesta

4

Desafortunadamente para llamar al A::Test(int) a través de una referencia B se necesita algún tipo de conversión. Siempre que el compilador de C# vea la referencia a través de B, elegirá la versión B::Test(double).

Una versión ligeramente menos feo es el siguiente

((A)this).Test(1); 

Otra idea de que es tener un método privado con un nombre diferente que tanto se alimentan en.

class B : A { 
    public override void Test(int i) { 
    TestCore(i); 
    } 
    public void Test(double d) { 
    TestCore(1); 
    } 
    private void TestCore(int i) { 
    // Combined logic here 
    } 
} 
5

resolución sobrecarga del método en C# no siempre se comporta como era de esperar, pero su código se comporta de acuerdo a la especificación (escribí a blog post sobre esto hace un tiempo).

En pocas palabras, el compilador empezar por la búsqueda de métodos que

  • tiene el mismo nombre (en su caso Test)
  • se declaran en el tipo (en su caso B) o uno de su base tipos
  • no se declaran con el modificador override

Tenga en cuenta que este último punto. Esto es realmente lógico, ya que los métodos virtuales se resuelven en tiempo de ejecución, no en tiempo de compilación.

Por último, si el tipo (en este caso B) tiene un método que es candidato (lo que significa que los parámetros en su llamada se pueden convertir implícitamente al tipo de parámetro del método candidato), ese método se usará . Su método reemplazado ni siquiera es parte del proceso de decisión.

Si desea llamar a su método reemplazado, primero deberá convertir el objeto a su tipo de base.

Cuestiones relacionadas