C# che chiama metodi della sottoclasse sottoposti a override senza sapere che si tratta di un'istanza della sottoclasse

StackOverflow https://stackoverflow.com/questions/390326

Domanda

Ho una classe base con un metodo virtuale e più sottoclassi che sovrascrivono quel metodo.

Quando incontro una di queste sottoclassi, vorrei chiamare il metodo sovrascritto, ma senza conoscere la sottoclasse.Mi vengono in mente modi brutti per farlo (controllare un valore e lanciarlo), ma sembra che dovrebbe esserci un modo nel linguaggio per farlo.Voglio che la Lista contenga più sottoclassi all'interno della stessa lista, altrimenti ovviamente potrei semplicemente creare una Lista.

MODIFICARE:Risolto il commento nel codice sbagliato, che ha portato alla prima risposta molto appropriata che ho ricevuto :)

Ad esempio:

Class Foo 
{
    public virtual printMe()
    {
        Console.Writeline("FOO");
    }
}

Class Bar : Foo 
{
    public override printMe()
    {
        Console.Writeline("BAR");
    }
}

List<Foo> list = new List<Foo>();
// then populate this list with various 'Bar' and other overriden Foos

foreach (Foo foo in list) 
{
    foo.printMe(); // prints FOO.. Would like it to print BAR
} 
È stato utile?

Soluzione

class Foo 
{
    public virtual void virtualPrintMe()
    {
        nonVirtualPrintMe();
    }

    public void nonVirtualPrintMe()
    {
        Console.Writeline("FOO");
    }
}

class Bar : Foo 
{
    public override void virtualPrintMe()
    {
        Console.Writeline("BAR");
    }
}

List<Foo> list = new List<Foo>();
// then populate this list with various 'Bar' and other overriden Foos

foreach (Foo foo in list) 
{
    foo.virtualPrintMe(); // prints BAR or FOO
    foo.nonVirtualPrintMe(); // always prints FOO
}

Altri suggerimenti

Perché dovrebbe stampare "Pippo"? Questo non è lo scopo di metodi virtuali. Il punto è che le classi derivate possono cambiare il modo in cui la funzione lavora senza cambiare l'interfaccia. Un oggetto Foo stamperà "Foo" e un oggetto bar stamperà "Bar". Tutto il resto sarebbe sbagliato.

Utilizzare il nuovo modificatore per nascondere in modo esplicito un membro ereditato da una classe base. Per nascondere un membro ereditato, dichiararla nella classe derivata utilizzando lo stesso nome, e modificarlo con il nuovo modificatore. Questo si tradurrà in esattamente il comportamento che si desidera.

Per maggiori informazioni vai qui: http://geekswithblogs.net/Mohamed/articles/28613 aspx

Per ottenere il comportamento desiderato in questa situazione è possibile rimuovere il virtuale sulla classe di base e utilizzare nuovi della sottoclasse.

Tuttavia, come Ed Swangren indicato, perché dovresti?

Non esiste una soluzione in cui lanci semplicemente l'oggetto che vuoi chiamare l'altro:

 foo.printMe(); // prints FOO.. Would like it to print BAR

diventa

(Foo)foo.printMe(); // foo can be any derived class of Foo.

Oppure mi sto perdendo qualche parte della domanda?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top