I metodi di sovrascrittura dovrebbero chiamare il metodo base?

3

Sto solo eseguendo NDepend contro un codice che ho scritto e uno degli avvertimenti è Overrides of Method() should call base.Method() .

Le posizioni in cui questo si verifica sono dove ho una classe base che ha proprietà e metodi virtuali con comportamento default ma che può essere sovrascritta da una classe che eredita dalla classe base e non chiama metodo sottoposto a override.

Ad esempio, nella classe base ho una proprietà definita in questo modo:

protected virtual char CloseQuote
{
    get
    {
        return '"';
    }
}

E poi in una classe ereditaria che usa una citazione di chiusura diversa:

protected override char CloseQuote
{
    get
    {
        return ']';
    }
}

Non tutte le classi che ereditano dalla classe base usano caratteri di virgoletta diversi, quindi il mio progetto iniziale.

Le alternative a cui pensavo erano proprietà get / set nella classe base con i valori di default impostati nel costruttore:

protected BaseClass()
{
    this.CloseQuote = '"';
}

protected char CloseQuote { get; set; }

public InheritingClass()
{
    this.CloseQuote = ']';
}

Oppure fai in modo che la classe base richieda i valori come argomenti del costruttore:

protected BaseClass(char closeQuote, ...)
{
    this.CloseQuote = '"';
}

protected char CloseQuote { get; private set; }

public InheritingClass()
    base (closeQuote: ']', ...)
{
}

Devo usare virtual in uno scenario in cui l'implementazione di base può essere sostituita anziché estesa o dovrei optare per una delle alternative che ho pensato? Se sì, quale sarebbe preferibile e perché?

    
posta Trevor Pilley 02.12.2012 - 17:36
fonte

3 risposte

3

È una decisione di progettazione valida avere un'implementazione predefinita di un metodo in una classe base che dovrebbe essere completamente sostituita quando il metodo è sovrascritto in una classe derivata.

Quindi potresti considerare gli avvertimenti di NDepend come falsi positivi per il tuo codice. Vorrei controllare la documentazione di NDepend per vedere se c'è un'opzione o un'annotazione del codice sorgente che dice a NDepend che non chiamare l'implementazione della classe base è corretta qui per sbarazzarsi della confusione.

Se non esiste tale opzione (o non funziona per le proprietà), la mia preferenza sarebbe la prima alternativa (sostituendo il valore di CloseQuote nel costruttore della classe derivata).

    
risposta data 02.12.2012 - 18:33
fonte
1

È uno strano avvertimento che NDepend ti offre. Sicuramente non tutti i metodi sottoposti a override hanno bisogno di chiamare il metodo base, quindi penso che il testo Method() should call base.Method() sia troppo strong. Sembra che tu stia facendo qualcosa di sbagliato, che chiaramente non lo sei.

Questo non ha nulla a che fare con l'utilizzo di virtual . Doveva essere una domanda diversa?

    
risposta data 02.12.2012 - 18:02
fonte
1

L'avviso sta cercando di dirti che, dal momento che hai definito una relazione is-a con la super classe, tutti i comportamenti protetti e pubblici della super classe dovrebbero essere raggiungibili dalla sottoclasse.

Molto spesso la vera ragione per cui si vuole sovrascrivere un metodo per sostituire completamente il proprio comportamento è una richiesta di composizione. Per esempio. invece di sovrascrivere il metodo closeQuote, potresti voler creare un'interfaccia 'QuoteDefinitionProvider' (o simile) e alimentarla alla superclasse.

Altri motivi potrebbero essere:

  • super class dovrebbe essere astratto, ma non lo è, quindi viene fornita un'implementazione 'default'. Soluzione: rendi super classe astratta.
  • l'implementazione della sottoclasse può essere ottimizzata per il caso speciale. Questo sembra essere un valido motivo per ignorare completamente il metodo e non chiamare super.

Quindi, prima di ignorare questo avviso, controlla se la tua situazione richiede la composizione invece dell'ereditarietà. Nella mia esperienza professionale, ho raramente trovato un vero bisogno di ereditarietà di classe.

    
risposta data 02.12.2012 - 19:07
fonte

Leggi altre domande sui tag