2012-03-28 13 views
6

ho semplificato il mio codice a questoclasse derivata utilizzando il metodo sbagliato

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     Child d = new Child(); 
     int i = 100; 
     d.AddToTotal(i); 

     Console.ReadKey(); 
    } 

    private class Parent 
    { 
     public virtual void AddToTotal(int x) 
     { 
      Console.WriteLine("Parent.AddToTotal(int)"); 
     } 
    } 

    private class Child : Parent 
    { 
     public override void AddToTotal(int number) 
     { 
      Console.WriteLine("Child.AddToTotal(int)"); 
     } 

     public void AddToTotal(double currency) 
     { 
      Console.WriteLine("Child.AddToTotal(double)"); 
     } 
    } 
} 

Il problema è che questo richiede

public void AddToTotal(double currency) 

anche se io chiamo con un int e si dovrebbe usare

public override void AddToTotal(int number) 

L'utilizzo del genitore restituisce il risultato previsto.

Parent d = new Child(); 
int i = 100; 
d.AddToTotal(i); 

Aggiornamento:

Grazie alla @Jan e @azyberezovsky per me che punta al specification. Ho aggiunto un metodo virtuale vuoto alla classe base per aggirare questo per ora.

+2

Beh, sono stato in grado di replicare i risultati, e garantire che non era solo un errore di battitura, in cui il nome del metodo del sovraccarico int era diverso. – Servy

+1

'd.AddToTotal (numero: i)' chiama il sovraccarico int, come previsto, ma non è necessario farlo ... – Servy

+3

Vedere questa risposta per una spiegazione: http://stackoverflow.com/a/1833268/25727 – Jan

risposta

8

Un member lookup di un nome N in un tipo T viene elaborato come segue:

Innanzitutto, l'insieme di tutti i membri accessibili nominati N dichiarato nella T ei tipi di base di T è costruito. dichiarazioni che includono un di override modificatore sono esclusi dal set. Se nessun membro denominato N esiste e è accessibile, la ricerca non produce corrispondenze e i seguenti passaggi non vengono valutati.

Così, quando si utilizza variabile di tipo Bambino

Child d = new Child(); 
int i = 100; 
d.AddToTotal(i); 

metodo public override void AddToTotal(int number) è esclusa dal set, e abbiamo solo un metodo con il nome N sinistro. Int è convertito implicitamente in double, quindi non si sono verificati errori.

+0

Trovo molto strano che la risoluzione di sovraccarico darebbe una maggiore priorità ai nuovi metodi rispetto ai metodi sovrascritti, ma apparentemente lo fa ... strano. Qualcuno sa qual è il ragionamento che sta dietro? – Servy

+1

@Servy vedi questa risposta di Eric Lippert per il ragionamento: http://stackoverflow.com/a/1833866/53777 –

+4

@Servy: Molte persone trovano questa scelta dispari, ma ci sono due ottimi motivi per farlo. La prima ragione è che * lo sviluppatore che ha scritto il metodo della classe derivata aveva più informazioni dello sviluppatore che ha scritto il metodo della classe base. * In particolare, lo sviluppatore della classe derivata sa quali sono i dettagli di implementazione della classe derivata, ma lo sviluppatore della classe base non. La risoluzione del sovraccarico dovrebbe scegliere il metodo che è stato scritto dal ragazzo che sapeva di più sull'oggetto che l'utente sta effettivamente utilizzando. –

1

This answer-this question spiega le ragioni tecniche per cui questo accade. Ho incluso la risposta in linea qui per comodità, ma tutto il credito è dovuto a tvanfosson.

Vedere la sezione del linguaggio C# Specifica il Member Lookup e Overload Resolution. Il metodo di sostituzione della classe derivata non è un candidato a causa delle norme in materia di Stati di ricerca e il metodo della classe base non è la migliore corrispondenza in base alle regole di sovraccarico Risoluzione .

Sezione 7,3

In primo luogo, l'insieme di tutti (sezione 3.5) membri nominati accessibili N dichiarato T ei tipi di base (sezione 7.3.1) di T è costruito. Le dichiarazioni che includono un modificatore override sono escluse dal set . Se nessun membro denominato N esiste e è accessibile, la ricerca non produce corrispondenze e i seguenti passaggi non vengono valutati.

Sezione 7.4.2:

Ciascuno di questi contesti definisce l'insieme di elementi funzionali candidati e l'elenco di argomenti a suo modo unico, come descritto in dettaglio nelle sezioni di cui sopra. Ad esempio, il gruppo di candidati per un richiamo del metodo non include i metodi contrassegnati da override (Sezione 7.3), ei metodi in una classe base non sono candidati se è applicabile un metodo in una classe derivata (Sezione 7.5.5.1). (sottolineatura mia)

Problemi correlati