2012-04-02 2 views
7

Ho il seguente codice sempliceCome chiamare il metodo sottoposto a override con sovraccarico?

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); 
    } 
} 

Quando ho eseguito questo codice la linea di prova ((Int32) 1) provoca overflow dello stack a causa di una ricorsione infinita. L'unico modo possibile per chiamare in modo corretto metodo corretto (con parametro intero) che ho trovato è

(this as A).Test(1); 

Ma questo non è appropriato per me, perché entrambi i metodi di prova sono pubbliche e sono disposto agli utenti di essere in grado di chiamare sia metodo?

risposta

4

Sfortunatamente per chiamare lo A::Test(int) tramite un riferimento B è necessaria una sorta di trasmissione. Finché il compilatore C# vede il riferimento tramite B sceglierà la versione B::Test(double).

Un po 'meno brutta versione è la seguente

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

Un altro pensiero se è avere un metodo privato con un nome diverso che sia alimentato nel.

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

risoluzione overload del metodo in C# non sempre si comporta come ci si potrebbe aspettare, ma il codice si comporta in base alle specifiche (ho scritto a blog post su questo qualche tempo fa).

In breve, il compilatore cominciare trovando metodi che

  • ha lo stesso nome (nel tuo caso Test)
  • sono dichiarati nel tipo (nel tuo caso B) o una delle sua base tipi
  • non vengono dichiarati con l'override modificatore di

Nota quest'ultimo punto. Questo è in realtà logico, poiché i metodi virtuali vengono risolti in fase di esecuzione, non in fase di compilazione.

Infine, se il tipo (in questo caso B) ha un metodo che è candidato (il che significa che i parametri della chiamata possono essere convertiti implicitamente nel tipo di parametro del metodo candidato), verrà utilizzato tale metodo . Il tuo metodo sovrascritto non fa nemmeno parte del processo decisionale.

Se si desidera chiamare il metodo sottoposto a override, è necessario prima eseguire il cast dell'oggetto nel suo tipo di base.