2010-02-20 19 views
14

Stavo facendo una revisione del codice oggi e ho trovato un vecchio codice scritto da qualche sviluppatore. E 'più o meno cosìmetodi astratti interni. Perché qualcuno dovrebbe averli?

public abstract class BaseControl 
{ 
    internal abstract void DoSomething(); 
} 

Se si dispone di una classe derivata all'interno della stessa assemblea, che avrebbe funzionato

public class DerivedControl : BaseControl 
{ 
    internal override void DoSomething() 
    { 
    } 
} 

Ma derivare la classe di base in un assembly diverso darebbe errore di compilazione tempo

DerivedControl does not implement inherited abstract member 'BaseControl.DoSomething() 

Questo mi ha fatto pensare. Perché qualcuno dovrebbe dichiarare un metodo come astratto interno?

risposta

12

Il programmatore originale voleva rendere disponibile un controllo derivato al codice client. Ma impedisci al client di ereditare e scherzare con il metodo virtuale. Non è una cattiva idea, di solito è facile rompere una classe base sovrascrivendo un metodo e facendo qualcosa come dimenticare di chiamare il metodo della classe base.

+0

Potrebbe non essere una cattiva idea fino alla quarta volta che ti sei imbattuto in questa supposizione condiscendente in una libreria di terze parti. Spesso significa una tonnellata di duplicazioni inutili. (DevExpress, ti sto guardando ...) – jnm2

1

La mia prima reazione è stata che non esiste una buona ragione, se si desidera impedire l'ereditarietà esterna, è necessario contrassegnare la classe interna. Ma ciò significa che la classe è totalmente nascosta ad altri assembly.

Suppongo che questo metodo prevenga l'ereditarietà esterna mantenendo la visibilità.

+1

No: se si desidera impedire l'ereditarietà esterna, si rende il costruttore interno. Non è necessario rendere l'intera classe interna. – RobSiklos

+0

Qual è la differenza tra rendere la classe interna e rendere il costruttore interno? – RSB

+0

@RobSiklos In quali scenari, si dovrebbe rendere la classe interna – RSB

6

Un caso ovvio è dove il metodo riceve o restituisce un tipo interno. Ad esempio, i metodi core delle classi WPF Transform elaborano alcuni tipi di interoperabilità interni, che WPF non espone come parte della sua API pubblica. Poiché la firma include tipi interni, il metodo non può essere pubblico o protetto. Eppure chiaramente è appropriato (necessario!) Che le varie classi di trasformazione funzionino in modo polimorfico. Pertanto i metodi di base in Transform/GeneralTransform devono essere interni.

Un altro motivo, ma correlato, è impedire la derivazione esterna. Dopo tutto, gli architetti WPF potevano aver esposto una versione "sicura" dei tipi di interoperabilità interni in un metodo astratto protetto, in modo che gli utenti potessero creare le proprie classi Transform. Non lo fecero perché non volevano dover affrontare i modi in cui le persone potevano usare quella capacità, ad es. creando trasformazioni non affini. Consentire la derivazione esterna avrebbe reso il lavoro di altre classi in WPF estremamente più complesso, così gli architetti hanno deciso di consentire solo classi derivate "approvate" facendo un metodo astratto interno.

0

Definendo un metodo come interno astratto si desidera assicurarsi che solo la classe nello stesso assieme possa avere la sua implementazione per il proprio metodo.

ora se si distribuisce una dll di esso questo eviterà al client di ereditare e mesup l'implementazione.

Problemi correlati