2011-10-15 10 views
51

In C# e C++/CLI la parola chiave sealed (o NotInheritable in VB) viene utilizzata per proteggere una classe da qualsiasi possibilità di ereditarietà (la classe non sarà ereditabile). So che una caratteristica della programmazione orientata agli oggetti è l'ereditarietà e ritengo che l'uso di sealed vada contro questa funzione, impedendo l'ereditarietà. C'è un esempio che mostra il vantaggio di sealed e quando è importante utilizzarlo?Quando e perché sigilleresti una lezione?

risposta

62

1) Su una classe che implementa funzionalità di sicurezza, in modo che l'oggetto originale non possa essere "impersonato".

2) Più in generale, di recente mi sono scambiato con una persona in Microsoft, che mi ha detto che cercava di limitare l'ereditarietà ai luoghi in cui aveva davvero senso, perché diventa costoso se non curato.
La parola chiave sealed indica al CLR che non esiste una classe più in basso per cercare i metodi e che accelera le cose.

Al giorno d'oggi nella maggior parte degli strumenti di miglioramento delle prestazioni sul mercato, troverete una casella di controllo che sigillerà tutte le vostre classi che non sono ereditate.
Attenzione però, perché se si desidera consentire i plug-in o il rilevamento degli assiemi tramite MEF, si verificheranno dei problemi.

+0

perché dovresti avere problemi con MEF se usi la classe sigillata? –

+3

Intendevo fare attenzione con le classi di tenuta nelle librerie riutilizzate, specialmente se sono riutilizzate da terzi e poi reintegrate (tramite MEF) nella base di codici. Il tuo codice base non può ereditare una determinata classe, ma terze parti lo faranno. –

+0

Il motivo # 1 suona vago ma, supponendo che non scriviamo "caratteristiche di sicurezza" il più delle volte, ciò significa che la ragione # 1 non si applica? Il motivo n. 2 riguarda la messa a punto delle prestazioni.Di quale differenza di prestazioni stiamo parlando? Sono abbastanza significativi da giustificare l'alterazione della definizione di una classe non di sicurezza? Anche se la risposta fosse "sì", sarebbe idealmente un'opzione di compilazione, ad esempio "generare codice ottimizzato per tutte le classi non sigillate", piuttosto che far sì che gli sviluppatori modifichino il codice base. – RayLuo

7

Un addendum alla risposta eccellente del Babbuino:

3) Se una classe non è progettato per l'eredità, le sottoclassi potrebbero rompersi class invariants. Questo si applica in realtà solo se stai creando un'API pubblica, ovviamente, ma come regola generale sigillo qualsiasi classe non esplicitamente progettata per essere sottoclasse.

Su una nota correlata, applicabile solo alle classi non sigillate: qualsiasi metodo creato virtual è un punto di estensione o, almeno, sembra che dovrebbe essere un punto di estensione. La dichiarazione dei metodi virtual dovrebbe essere una decisione consapevole. (In C# questa è una decisione consapevole, in Java non è così.)


EDIT: Alcuni link rilevanti:

Si noti inoltre che Kotlin sigilli classi di default; its open keyword is the opposite of Java's final or the sealed of C#. (Per essere sicuri, there is no universal agreement that this is a good thing.)

+8

Le classi di sigillatura causano più mal di testa che beneficio. Ho trovato continuamente situazioni in cui gli sviluppatori hanno classi sigillate, causandomi ore di difficoltà in ciò che dovrebbe essere semplice. Smetti di frequentare le lezioni, non sei così spiritoso come credi di essere. Sigilla le classi solo se DEVI, e anche allora, riconsiderare. Solo la mia opinione, come il ragazzo che ha a che fare con classi sigillate di altre persone che non posso modificare/annullare. – GantMan

+2

Il commento di @GantMan dovrebbe essere considerato una delle risposte alla domanda dell'OP, perché essenzialmente fornisce una risposta come "Quando? Difficilmente, perché?" Questo è il motivo per cui NON lo fai. " Concedi di postare nuovamente il tuo commento come risposta separata e poi raccogliere voti per questo. :-) – RayLuo

-1

Penso che questo post abbia un buon punto, il caso specifico è stato quando si prova a trasmettere una classe non sigillata a qualsiasi interfaccia casuale, il compilatore non genera errori; ma una volta sigillato viene usato il compilatore genera errore che non può convertire. La classe sigillata offre sicurezza aggiuntiva per l'accesso al codice.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla

+1

Un collegamento a una soluzione è il benvenuto, ma per favore assicurati che la tua risposta sia utile senza di essa: [aggiungi contesto intorno al link] (// meta.stackexchange.com/a/8259) in modo che i tuoi utenti abbiano qualche idea che cos'è e perché è lì, quindi cita la parte più pertinente della pagina a cui stai collegando nel caso in cui la pagina di destinazione non sia disponibile. [Le risposte che sono poco più di un collegamento possono essere cancellate.] (// stackoverflow.com/help/deleted-answers) –

+0

Scusa se non ho intenzione di postarlo come risposta, ma sembra non correlato ad altre risposte e io non so dove metterlo – strisunshine

+0

Ho modificato il post in base al suggerimento. Inizialmente vorrei solo contribuire con un angolo diverso (forse), ma ho solo ottenuto un downvote e non abbiamo ancora parlato del contenuto, potevamo il -1 gentilmente far sapere il motivo? – strisunshine

Problemi correlati